mirror of
https://github.com/spectreconsole/spectre.console.git
synced 2025-10-25 15:19:23 +00:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4dda283bb | ||
|
|
da9c6ee4c2 | ||
|
|
855127f32a | ||
|
|
fa731070d8 | ||
|
|
ef08c5bf2b | ||
|
|
1c769c6610 | ||
|
|
1cd335e785 | ||
|
|
29e6e34f83 | ||
|
|
bff3438a5a | ||
|
|
c64884854f | ||
|
|
3a42c0a119 | ||
|
|
525b414ff8 | ||
|
|
ed0fb29be4 | ||
|
|
04d0e663d5 | ||
|
|
17ee8990f4 | ||
|
|
a1050fc676 | ||
|
|
9312663bde | ||
|
|
102e2dc38d | ||
|
|
28e9c14de4 | ||
|
|
fd217ffc83 | ||
|
|
95ec04df40 | ||
|
|
705cf745ea | ||
|
|
b64e016e8c | ||
|
|
58400fe74e | ||
|
|
e20f6284f9 | ||
|
|
953008b5e3 | ||
|
|
ad49b6aa67 | ||
|
|
31a5e17a45 | ||
|
|
f06dc7e7d8 | ||
|
|
a23bec4082 | ||
|
|
913a7b1e37 | ||
|
|
63bae278a9 | ||
|
|
1a747696a8 | ||
|
|
994540d97f | ||
|
|
dee3c01629 | ||
|
|
a3e11b24e5 | ||
|
|
35568ab823 | ||
|
|
07db28bb6f | ||
|
|
d87d8e4422 |
77
README.fa.md
Normal file
77
README.fa.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# `Spectre.Console`
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
|
||||
<div dir="rtl">
|
||||
|
||||
یک کتابخانه NET Standard 2.0/.NET 5. که ایجاد Console Applicationهای زیبا و cross platform را آسانتر میکند.
|
||||
از کتابخانه عالی [Rich](https://github.com/willmcgugan/rich) برای پایتون، بسیار الهام گرفته شده است.
|
||||
|
||||
## فهرست
|
||||
|
||||
1. [امکانات](#features)
|
||||
2. [نصب](#installing)
|
||||
3. [مستندات](#documentation)
|
||||
4. [مثالها](#examples)
|
||||
5. [مجوز](#license)
|
||||
|
||||
<h2 id="features">امکانات</h2>
|
||||
|
||||
* با در نظر گرفتن تست واحد نوشته شده است.
|
||||
* جداول، چارچوبها، پنلها و یک زبان نشانه گذاری که از [rich](https://github.com/willmcgugan/rich) الهام گرفته شده است را پشتیبانی میکند.
|
||||
* از رایج ترین پارامترهای SRG در هنگام فرم دهی متن مانند پررنگ، کم نور، اریب، زیرخط، خط زدن و چشمک زدن پشتیبانی میکند.
|
||||
* پشتیبانی از رنگهای 28/8/4/3-بیت در ترمینال.
|
||||
این کتابخانه توانایی ترمینال فعلی را تشخیص داده و در صورت لزوم رنگها را کاهش میدهد.
|
||||
|
||||
|
||||

|
||||
|
||||
<h2 id="installing">نصب</h2>
|
||||
|
||||
سریع ترین راه برای شروع `Spectre.Console` نصب از طریق NuGet Package میباشد.
|
||||
|
||||
<pre dir="ltr">
|
||||
dotnet add package Spectre.Console
|
||||
</pre>
|
||||
|
||||
<h2 id="documentation">مستندات</h2>
|
||||
|
||||
مستندات `Spectre.Console` را در اینجا میتوایند پیدا کنید:
|
||||
|
||||
<div dir="ltr">
|
||||
https://spectresystems.github.io/spectre.console/
|
||||
</div>
|
||||
|
||||
<h2 id="examples">مثالها</h2>
|
||||
|
||||
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||
را نصب کنید.
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet tool restore
|
||||
</pre>
|
||||
|
||||
حالا شما میتوانید مثالهای موجود در این مخزن را لیست کنید:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example
|
||||
</pre>
|
||||
|
||||
و برای اجرای مثال:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example tables
|
||||
</pre>
|
||||
|
||||
<h2 id="license">مجوز</h2>
|
||||
|
||||
<div dir="ltr">
|
||||
Copyright © Spectre Systems.
|
||||
</div>
|
||||
|
||||
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
||||
|
||||
* برای SixLabors.ImageSharp، مشاهده کنید: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@ Python用の素晴らしい[Rich ライブラリ](https://github.com/willmcgugan
|
||||
|
||||
## 例
|
||||
|
||||

|
||||

|
||||
|
||||
## 使用方法
|
||||
|
||||
@@ -111,6 +111,7 @@ Spectre.Consoleでできることを見るために、
|
||||
│ Panels │ examples/Panels/Panels.csproj │ Demonstrates how to render items in panels. │
|
||||
│ Rules │ examples/Rules/Rules.csproj │ Demonstrates how to render horizontal rules (lines). │
|
||||
│ Tables │ examples/Tables/Tables.csproj │ Demonstrates how to render tables in a console. │
|
||||
│ Trees │ examples/Trees/Trees.csproj │ Demonstrates how to render trees in a console. │
|
||||
╰────────────┴───────────────────────────────────────┴──────────────────────────────────────────────────────╯
|
||||
```
|
||||
|
||||
|
||||
21
README.md
21
README.md
@@ -12,6 +12,7 @@ for Python.
|
||||
2. [Installing](#installing)
|
||||
3. [Documentation](#documentation)
|
||||
4. [Examples](#examples)
|
||||
5. [Sponsors](#sponsors)
|
||||
5. [License](#license)
|
||||
|
||||
## Features
|
||||
@@ -26,7 +27,7 @@ for Python.
|
||||
and downgrade colors as needed.
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
@@ -63,6 +64,24 @@ And to run an example:
|
||||
> dotnet example tables
|
||||
```
|
||||
|
||||
## Sponsors
|
||||
|
||||
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||
Spectre.Console to show their support and to ensure the longevity of the project.
|
||||
|
||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||
* [Dave Glick](https://github.com/daveaglick)
|
||||
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||
* [Viktor Elofsson](https://github.com/vktr)
|
||||
* [Steven Knox](https://github.com/stevenknox)
|
||||
* [David Pendray](https://github.com/dpen2000)
|
||||
|
||||
I really appreciate it.
|
||||
**Thank you very much!**
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Spectre Systems.
|
||||
|
||||
@@ -7,7 +7,7 @@ To start contributing to the [Spectre.Console](https://github.com/spectresystems
|
||||
The documentation site uses [Statiq](https://statiq.dev), a static site generator. To build the documentation site run the following in a command-line terminal.
|
||||
|
||||
```
|
||||
> dotnet run preview --virtual-dir "spectre.console"
|
||||
> Preview.ps1
|
||||
```
|
||||
|
||||
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
|
||||
@@ -29,13 +29,7 @@ Layout and styling can also be found in the [input](./input) directory. Look for
|
||||
|
||||
## Custom Build Features
|
||||
|
||||
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory. Enhancements to the build process include:
|
||||
|
||||
- [Extension Methods](./src/Extensions)
|
||||
- [Models](./src/Models)
|
||||
- [Pipelines](./src/Pipelines)
|
||||
- [Shortcodes](./src/Shortcodes)
|
||||
- [Utilities](./src/Utilities)
|
||||
The documentation site has custom enhancements to Statiq located under the [./src](./src) directory.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
BIN
docs/input/assets/images/example.png
Normal file
BIN
docs/input/assets/images/example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 219 KiB |
@@ -58,17 +58,19 @@ in the previous step.
|
||||
```csharp
|
||||
public class AddPackageCommand : Command<AddPackageSettings>
|
||||
{
|
||||
public override int Execute(AddPackageSettings settings, ILookup<string, string> remaining)
|
||||
public override int Execute(CommandContext context, AddPackageSettings settings)
|
||||
{
|
||||
// Omitted
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class AddReferenceCommand : Command<AddReferenceSettings>
|
||||
{
|
||||
public override int Execute(AddReferenceSettings settings, ILookup<string, string> remaining)
|
||||
public override int Execute(CommandContext context, AddReferenceSettings settings)
|
||||
{
|
||||
// Omitted
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -2,7 +2,7 @@ Title: Exceptions
|
||||
Order: 3
|
||||
---
|
||||
|
||||
Exceptions isn't always readable when viewed in the terminal.
|
||||
Exceptions aren't always readable when viewed in the terminal.
|
||||
You can make exception a bit more readable by using the `WriteException` method.
|
||||
|
||||
```csharp
|
||||
|
||||
@@ -22,5 +22,5 @@ for Python written by Will McGugan.
|
||||
|
||||
## Examples
|
||||
|
||||
<img src="assets/images/table.gif" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
||||
<img src="https://github.com/spectresystems/spectre.console/raw/main/resources/gfx/screenshots/example.png" style="max-width: 100%;" />
|
||||
<img src="./assets/images/example.png" style="max-width: 100%; margin-top: 15px; margin-bottom: 25px;" />
|
||||
<img src="./assets/images/table.gif" style="max-width: 100%;" />
|
||||
|
||||
@@ -63,6 +63,7 @@ await AnsiConsole.Progress()
|
||||
AnsiConsole.Progress()
|
||||
.AutoRefresh(false) // Turn off auto refresh
|
||||
.AutoClear(false) // Do not remove the task list when done
|
||||
.HideCompleted(false) // Hide tasks as they are completed
|
||||
.Columns(new ProgressColumn[]
|
||||
{
|
||||
new TaskDescriptionColumn(), // Task description
|
||||
|
||||
19
docs/input/sponsors.md
Normal file
19
docs/input/sponsors.md
Normal file
@@ -0,0 +1,19 @@
|
||||
Title: Sponsors
|
||||
Order: 0
|
||||
---
|
||||
|
||||
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||
Spectre.Console to show their support and to ensure the longevity of the project.
|
||||
|
||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||
* [Dave Glick](https://github.com/daveaglick)
|
||||
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||
* [Viktor Elofsson](https://github.com/vktr)
|
||||
* [Steven Knox](https://github.com/stevenknox)
|
||||
* [David Pendray](https://github.com/dpen2000)
|
||||
|
||||
I really appreciate it.
|
||||
**Thank you very much!**
|
||||
@@ -27,5 +27,15 @@ namespace Injection
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, (provider) => func());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
examples/Cli/Logging/Commands/HelloCommand.cs
Normal file
35
examples/Cli/Logging/Commands/HelloCommand.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Commands
|
||||
{
|
||||
public class HelloCommand : Command<HelloCommand.Settings>
|
||||
{
|
||||
private ILogger<HelloCommand> _logger;
|
||||
private IAnsiConsole _console;
|
||||
|
||||
public HelloCommand(IAnsiConsole console, ILogger<HelloCommand> logger)
|
||||
{
|
||||
_console = console;
|
||||
_logger = logger;
|
||||
_logger.LogDebug("{0} initialized", nameof(HelloCommand));
|
||||
}
|
||||
|
||||
public class Settings : LogCommandSettings
|
||||
{
|
||||
[CommandArgument(0, "[Name]")]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public override int Execute(CommandContext context, Settings settings)
|
||||
{
|
||||
_logger.LogInformation("Starting my command");
|
||||
AnsiConsole.MarkupLine($"Hello, [blue]{settings.Name}[/]");
|
||||
_logger.LogInformation("Completed my command");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
examples/Cli/Logging/Commands/LogCommandSettings.cs
Normal file
56
examples/Cli/Logging/Commands/LogCommandSettings.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Serilog.Events;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging.Commands
|
||||
{
|
||||
public class LogCommandSettings : CommandSettings
|
||||
{
|
||||
[CommandOption("--logFile")]
|
||||
[Description("Path and file name for logging")]
|
||||
public string LogFile { get; set; }
|
||||
|
||||
[CommandOption("--logLevel")]
|
||||
[Description("Minimum level for logging")]
|
||||
[TypeConverter(typeof(VerbosityConverter))]
|
||||
[DefaultValue(LogEventLevel.Information)]
|
||||
public LogEventLevel LogLevel { get; set; }
|
||||
}
|
||||
|
||||
public sealed class VerbosityConverter : TypeConverter
|
||||
{
|
||||
private readonly Dictionary<string, LogEventLevel> _lookup;
|
||||
|
||||
public VerbosityConverter()
|
||||
{
|
||||
_lookup = new Dictionary<string, LogEventLevel>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{"d", LogEventLevel.Debug},
|
||||
{"v", LogEventLevel.Verbose},
|
||||
{"i", LogEventLevel.Information},
|
||||
{"w", LogEventLevel.Warning},
|
||||
{"e", LogEventLevel.Error},
|
||||
{"f", LogEventLevel.Fatal}
|
||||
};
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string stringValue)
|
||||
{
|
||||
var result = _lookup.TryGetValue(stringValue, out var verbosity);
|
||||
if (!result)
|
||||
{
|
||||
const string format = "The value '{0}' is not a valid verbosity.";
|
||||
var message = string.Format(CultureInfo.InvariantCulture, format, value);
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
return verbosity;
|
||||
}
|
||||
throw new NotSupportedException("Can't convert value to verbosity.");
|
||||
}
|
||||
}
|
||||
}
|
||||
20
examples/Cli/Logging/Infrastructure/LogInterceptor.cs
Normal file
20
examples/Cli/Logging/Infrastructure/LogInterceptor.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Logging.Commands;
|
||||
using Serilog.Core;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging
|
||||
{
|
||||
public class LogInterceptor : ICommandInterceptor
|
||||
{
|
||||
public static readonly LoggingLevelSwitch LogLevel = new();
|
||||
|
||||
public void Intercept(CommandContext context, CommandSettings settings)
|
||||
{
|
||||
if (settings is LogCommandSettings logSettings)
|
||||
{
|
||||
LoggingEnricher.Path = logSettings.LogFile ?? "application.log";
|
||||
LogLevel.MinimumLevel = logSettings.LogLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
examples/Cli/Logging/Infrastructure/LoggingEnricher.cs
Normal file
38
examples/Cli/Logging/Infrastructure/LoggingEnricher.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Logging
|
||||
{
|
||||
internal class LoggingEnricher : ILogEventEnricher
|
||||
{
|
||||
private string _cachedLogFilePath;
|
||||
private LogEventProperty _cachedLogFilePathProperty;
|
||||
|
||||
// this path and level will be set by the LogInterceptor.cs after parsing the settings
|
||||
public static string Path = string.Empty;
|
||||
|
||||
public const string LogFilePathPropertyName = "LogFilePath";
|
||||
|
||||
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
|
||||
{
|
||||
// the settings might not have a path or we might not be within a command in which case
|
||||
// we won't have the setting so a default value for the log file will be required
|
||||
LogEventProperty logFilePathProperty;
|
||||
|
||||
if (_cachedLogFilePathProperty != null && Path.Equals(_cachedLogFilePath))
|
||||
{
|
||||
// Path hasn't changed, so let's use the cached property
|
||||
logFilePathProperty = _cachedLogFilePathProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've got a new path for the log. Let's create a new property
|
||||
// and cache it for future log events to use
|
||||
_cachedLogFilePath = Path;
|
||||
_cachedLogFilePathProperty = logFilePathProperty = propertyFactory.CreateProperty(LogFilePathPropertyName, Path);
|
||||
}
|
||||
|
||||
logEvent.AddPropertyIfAbsent(logFilePathProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
examples/Cli/Logging/Infrastructure/TypeRegistrar.cs
Normal file
41
examples/Cli/Logging/Infrastructure/TypeRegistrar.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging
|
||||
{
|
||||
public sealed class TypeRegistrar : ITypeRegistrar
|
||||
{
|
||||
private readonly IServiceCollection _builder;
|
||||
|
||||
public TypeRegistrar(IServiceCollection builder)
|
||||
{
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return new TypeResolver(_builder.BuildServiceProvider());
|
||||
}
|
||||
|
||||
public void Register(Type service, Type implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type service, object implementation)
|
||||
{
|
||||
_builder.AddSingleton(service, implementation);
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> func)
|
||||
{
|
||||
if (func is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(func));
|
||||
}
|
||||
|
||||
_builder.AddSingleton(service, _ => func());
|
||||
}
|
||||
}
|
||||
}
|
||||
21
examples/Cli/Logging/Infrastructure/TypeResolver.cs
Normal file
21
examples/Cli/Logging/Infrastructure/TypeResolver.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Logging
|
||||
{
|
||||
public sealed class TypeResolver : ITypeResolver
|
||||
{
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public TypeResolver(IServiceProvider provider)
|
||||
{
|
||||
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
public object Resolve(Type type)
|
||||
{
|
||||
return _provider.GetRequiredService(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
examples/Cli/Logging/Logging.csproj
Normal file
26
examples/Cli/Logging/Logging.csproj
Normal file
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<ExampleName>Logging</ExampleName>
|
||||
<ExampleDescription>Demonstrates how to dynamically configure Serilog for logging using parameters from a command.</ExampleDescription>
|
||||
<ExampleGroup>Cli</ExampleGroup>
|
||||
<ExampleVisible>false</ExampleVisible>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Spectre.Console\Spectre.Console.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
54
examples/Cli/Logging/Program.cs
Normal file
54
examples/Cli/Logging/Program.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Logging.Commands;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
/*
|
||||
* Dynamically control serilog configuration via command line parameters
|
||||
*
|
||||
* This works around the chicken and egg situation with configuring serilog via the command line.
|
||||
* The logger needs to be configured prior to executing the parser, but the logger needs the parsed values
|
||||
* to be configured. By using serilog.sinks.map we can defer configuration. We use a LogLevelSwitch to control the
|
||||
* logging levels dynamically, and then we use a serilog enricher that has it's state populated via a
|
||||
* Spectre.Console CommandInterceptor
|
||||
*/
|
||||
|
||||
namespace Logging
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
static int Main(string[] args)
|
||||
{
|
||||
// to retrieve the log file name, we must first parse the command settings
|
||||
// this will require us to delay setting the file path for the file writer.
|
||||
// With serilog we can use an enricher and Serilog.Sinks.Map to dynamically
|
||||
// pull this setting.
|
||||
var serviceCollection = new ServiceCollection()
|
||||
.AddLogging(configure =>
|
||||
configure.AddSerilog(new LoggerConfiguration()
|
||||
// log level will be dynamically be controlled by our log interceptor upon running
|
||||
.MinimumLevel.ControlledBy(LogInterceptor.LogLevel)
|
||||
// the log enricher will add a new property with the log file path from the settings
|
||||
// that we can use to set the path dynamically
|
||||
.Enrich.With<LoggingEnricher>()
|
||||
// serilog.sinks.map will defer the configuration of the sink to be ondemand
|
||||
// allowing us to look at the properties set by the enricher to set the path appropriately
|
||||
.WriteTo.Map(LoggingEnricher.LogFilePathPropertyName,
|
||||
(logFilePath, wt) => wt.File($"{logFilePath}"), 1)
|
||||
.CreateLogger()
|
||||
)
|
||||
);
|
||||
|
||||
var registrar = new TypeRegistrar(serviceCollection);
|
||||
var app = new CommandApp(registrar);
|
||||
|
||||
app.Configure(config =>
|
||||
{
|
||||
config.SetInterceptor(new LogInterceptor()); // add the interceptor
|
||||
config.AddCommand<HelloCommand>("hello");
|
||||
});
|
||||
|
||||
return app.Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<ExampleTitle>Canvas</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to render pixels and images.</ExampleDescription>
|
||||
<ExampleGroup>Widgets</ExampleGroup>
|
||||
@@ -14,9 +14,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="cake.png">
|
||||
<EmbeddedResource Include="cake.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
@@ -23,6 +25,16 @@ namespace CanvasExample
|
||||
image.NoMaxWidth();
|
||||
image.Mutate(ctx => ctx.Grayscale().Rotate(-45).EntropyCrop());
|
||||
Render(image, "Image from file (fit, greyscale, rotated)");
|
||||
|
||||
// Draw image again, but load from embedded resource rather than file
|
||||
using (var fileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Canvas.cake.png"))
|
||||
{
|
||||
Debug.Assert(fileStream != null);
|
||||
var embeddedImage = new CanvasImage(fileStream);
|
||||
embeddedImage.BilinearResampler();
|
||||
embeddedImage.MaxWidth(16);
|
||||
Render(embeddedImage, "Image from embedded resource (16 wide)");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Render(IRenderable canvas, string title)
|
||||
|
||||
@@ -1,21 +1,42 @@
|
||||
using Spectre.Console;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace InfoExample
|
||||
namespace Charts
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var chart = new BarChart()
|
||||
// Render a bar chart
|
||||
AnsiConsole.WriteLine();
|
||||
Render("Fruits per month", new BarChart()
|
||||
.Width(60)
|
||||
.Label("[green bold underline]Number of fruits[/]")
|
||||
.CenterLabel()
|
||||
.AddItem("Apple", 12, Color.Yellow)
|
||||
.AddItem("Orange", 54, Color.Green)
|
||||
.AddItem("Banana", 33, Color.Red);
|
||||
.AddItem("Banana", 33, Color.Red));
|
||||
|
||||
// Render a breakdown chart
|
||||
AnsiConsole.WriteLine();
|
||||
AnsiConsole.Render(chart);
|
||||
Render("Languages used", new BreakdownChart()
|
||||
.FullSize()
|
||||
.Width(60)
|
||||
.ShowPercentage()
|
||||
.AddItem("SCSS", 37, Color.Red)
|
||||
.AddItem("HTML", 28.3, Color.Blue)
|
||||
.AddItem("C#", 22.6, Color.Green)
|
||||
.AddItem("JavaScript", 6, Color.Yellow)
|
||||
.AddItem("Ruby", 6, Color.LightGreen)
|
||||
.AddItem("Shell", 0.1, Color.Aqua));
|
||||
}
|
||||
|
||||
private static void Render(string title, IRenderable chart)
|
||||
{
|
||||
AnsiConsole.Render(
|
||||
new Panel(chart)
|
||||
.Padding(1, 1)
|
||||
.Header(title));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ColorExample
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
if (AnsiConsole.Capabilities.ColorSystem == ColorSystem.NoColors)
|
||||
if (AnsiConsole.Profile.ColorSystem == ColorSystem.NoColors)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// No colors
|
||||
@@ -16,7 +16,7 @@ namespace ColorExample
|
||||
return;
|
||||
}
|
||||
|
||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.Legacy))
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Legacy))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 3-BIT
|
||||
@@ -39,7 +39,7 @@ namespace ColorExample
|
||||
}
|
||||
}
|
||||
|
||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.Standard))
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.Standard))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 4-BIT
|
||||
@@ -62,7 +62,7 @@ namespace ColorExample
|
||||
}
|
||||
}
|
||||
|
||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.EightBit))
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.EightBit))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 8-BIT
|
||||
@@ -89,7 +89,7 @@ namespace ColorExample
|
||||
}
|
||||
}
|
||||
|
||||
if (AnsiConsole.Capabilities.Supports(ColorSystem.TrueColor))
|
||||
if (AnsiConsole.Profile.Supports(ColorSystem.TrueColor))
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// 24-BIT
|
||||
|
||||
@@ -9,12 +9,16 @@ namespace InfoExample
|
||||
var grid = new Grid()
|
||||
.AddColumn(new GridColumn().NoWrap().PadRight(4))
|
||||
.AddColumn()
|
||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Capabilities.ColorSystem}")
|
||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsAnsi)}")
|
||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Capabilities.LegacyConsole)}")
|
||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Capabilities.SupportsInteraction)}")
|
||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Width}")
|
||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Height}");
|
||||
.AddRow("[b]Enrichers[/]", string.Join(", ", AnsiConsole.Profile.Enrichers))
|
||||
.AddRow("[b]Color system[/]", $"{AnsiConsole.Profile.ColorSystem}")
|
||||
.AddRow("[b]Supports ansi?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Ansi)}")
|
||||
.AddRow("[b]Supports links?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Links)}")
|
||||
.AddRow("[b]Legacy console?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Legacy)}")
|
||||
.AddRow("[b]Interactive?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Interactive)}")
|
||||
.AddRow("[b]TTY?[/]", $"{YesNo(AnsiConsole.Profile.Capabilities.Tty)}")
|
||||
.AddRow("[b]Buffer width[/]", $"{AnsiConsole.Console.Profile.Width}")
|
||||
.AddRow("[b]Buffer height[/]", $"{AnsiConsole.Console.Profile.Height}")
|
||||
.AddRow("[b]Encoding[/]", $"{AnsiConsole.Console.Profile.Encoding.EncodingName}");
|
||||
|
||||
AnsiConsole.Render(
|
||||
new Panel(grid)
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace LinkExample
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
if (AnsiConsole.Capabilities.SupportLinks)
|
||||
if (AnsiConsole.Profile.Capabilities.Links)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[link=https://patriksvensson.se]Click to visit my blog[/]!");
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Cursor
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Check if we can accept key strokes
|
||||
if (!AnsiConsole.Capabilities.SupportsInteraction)
|
||||
if (!AnsiConsole.Profile.Capabilities.Interactive)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[red]Environment does not support interaction.[/]");
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>9</LangVersion>
|
||||
<ExampleTitle>Prompt</ExampleTitle>
|
||||
<ExampleDescription>Demonstrates how to get input from a user.</ExampleDescription>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 247 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
@@ -19,4 +19,4 @@ if(!$?) {
|
||||
Pop-Location
|
||||
|
||||
# Copy the files to the correct location
|
||||
Copy-Item (Join-Path "$Output" "Spinner.Generated.cs") -Destination "$Source/Progress/Spinner.Generated.cs"
|
||||
Copy-Item (Join-Path "$Output" "Spinner.Generated.cs") -Destination "$Source/Widgets/Progress/Spinner.Generated.cs"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -10,7 +9,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
namespace Spectre.Console
|
||||
{
|
||||
internal static partial class ColorPalette
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -11,7 +10,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Spectre.Console.Internal
|
||||
namespace Spectre.Console
|
||||
{
|
||||
internal static partial class ColorTable
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Generated {{ date.now | date.to_string `%F %R` }}
|
||||
//
|
||||
// Partly generated from
|
||||
// https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.ImageSharp.Processing.Processors.Transforms;
|
||||
@@ -51,6 +52,24 @@ namespace Spectre.Console
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(filename);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Buffer containing an image.</param>
|
||||
public CanvasImage(ReadOnlySpan<byte> data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CanvasImage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Stream containing an image.</param>
|
||||
public CanvasImage(Stream data)
|
||||
{
|
||||
Image = SixLabors.ImageSharp.Image.Load<Rgba32>(data);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override Measurement Measure(RenderContext context, int maxWidth)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net5.0;netstandard2.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>true</IsPackable>
|
||||
<Description>A library that extends Spectre.Console with ImageSharp superpowers.</Description>
|
||||
|
||||
@@ -7,6 +7,9 @@ dotnet_diagnostic.CS1591.severity = none
|
||||
# SA1600: Elements should be documented
|
||||
dotnet_diagnostic.SA1600.severity = none
|
||||
|
||||
# SA1200: Using directives should be placed correctly
|
||||
dotnet_diagnostic.SA1200.severity = none
|
||||
|
||||
# Default severity for analyzer diagnostics with category 'StyleCop.CSharp.OrderingRules'
|
||||
dotnet_analyzer_diagnostic.category-StyleCop.CSharp.OrderingRules.severity = none
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Testing
|
||||
@@ -13,10 +12,7 @@ namespace Spectre.Console.Testing
|
||||
|
||||
public string Output => _writer.ToString();
|
||||
|
||||
public Capabilities Capabilities => _console.Capabilities;
|
||||
public Encoding Encoding => _console.Encoding;
|
||||
public int Width { get; }
|
||||
public int Height => _console.Height;
|
||||
public Profile Profile => _console.Profile;
|
||||
public IAnsiConsoleCursor Cursor => _console.Cursor;
|
||||
public FakeConsoleInput Input { get; }
|
||||
public RenderPipeline Pipeline => _console.Pipeline;
|
||||
@@ -24,21 +20,26 @@ namespace Spectre.Console.Testing
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
|
||||
public FakeAnsiConsole(
|
||||
ColorSystem system, AnsiSupport ansi = AnsiSupport.Yes,
|
||||
InteractionSupport interaction = InteractionSupport.Yes,
|
||||
ColorSystem system,
|
||||
AnsiSupport ansi = AnsiSupport.Yes,
|
||||
int width = 80)
|
||||
{
|
||||
_writer = new StringWriter();
|
||||
_console = AnsiConsole.Create(new AnsiConsoleSettings
|
||||
|
||||
var factory = new AnsiConsoleFactory();
|
||||
_console = factory.Create(new AnsiConsoleSettings
|
||||
{
|
||||
Ansi = ansi,
|
||||
ColorSystem = (ColorSystemSupport)system,
|
||||
Interactive = interaction,
|
||||
Out = _writer,
|
||||
LinkIdentityGenerator = new FakeLinkIdentityGenerator(1024),
|
||||
Enrichment = new ProfileEnrichment
|
||||
{
|
||||
UseDefaultEnrichers = false,
|
||||
},
|
||||
});
|
||||
|
||||
Width = width;
|
||||
_console.Profile.Width = width;
|
||||
|
||||
Input = new FakeConsoleInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,24 +9,13 @@ namespace Spectre.Console.Testing
|
||||
{
|
||||
public sealed class FakeConsole : IAnsiConsole, IDisposable
|
||||
{
|
||||
public Capabilities Capabilities { get; }
|
||||
public Encoding Encoding { get; }
|
||||
public Profile Profile { get; }
|
||||
public IAnsiConsoleCursor Cursor => new FakeAnsiConsoleCursor();
|
||||
public FakeConsoleInput Input { get; }
|
||||
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
|
||||
IAnsiConsoleInput IAnsiConsole.Input => Input;
|
||||
public RenderPipeline Pipeline { get; }
|
||||
|
||||
public Decoration Decoration { get; set; }
|
||||
public Color Foreground { get; set; }
|
||||
public Color Background { get; set; }
|
||||
public string Link { get; set; }
|
||||
|
||||
public StringWriter Writer { get; }
|
||||
public string Output => Writer.ToString();
|
||||
public FakeConsoleInput Input { get; }
|
||||
public string Output => Profile.Out.ToString();
|
||||
public IReadOnlyList<string> Lines => Output.TrimEnd('\n').Split(new char[] { '\n' });
|
||||
|
||||
public FakeConsole(
|
||||
@@ -34,18 +23,22 @@ namespace Spectre.Console.Testing
|
||||
bool supportsAnsi = true, ColorSystem colorSystem = ColorSystem.Standard,
|
||||
bool legacyConsole = false, bool interactive = true)
|
||||
{
|
||||
Capabilities = new Capabilities(supportsAnsi, colorSystem, legacyConsole, interactive);
|
||||
Encoding = encoding ?? Encoding.UTF8;
|
||||
Width = width;
|
||||
Height = height;
|
||||
Writer = new StringWriter();
|
||||
Input = new FakeConsoleInput();
|
||||
Pipeline = new RenderPipeline();
|
||||
|
||||
Profile = new Profile(new StringWriter(), encoding ?? Encoding.UTF8);
|
||||
Profile.Width = width;
|
||||
Profile.Height = height;
|
||||
Profile.ColorSystem = colorSystem;
|
||||
Profile.Capabilities.Ansi = supportsAnsi;
|
||||
Profile.Capabilities.Legacy = legacyConsole;
|
||||
Profile.Capabilities.Interactive = interactive;
|
||||
Profile.Capabilities.Links = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Writer.Dispose();
|
||||
Profile.Out.Dispose();
|
||||
}
|
||||
|
||||
public void Clear(bool home)
|
||||
@@ -61,7 +54,7 @@ namespace Spectre.Console.Testing
|
||||
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
Writer.Write(segment.Text);
|
||||
Profile.Out.Write(segment.Text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Spectre.Console.Testing
|
||||
{
|
||||
public sealed class FakeLinkIdentityGenerator : ILinkIdentityGenerator
|
||||
{
|
||||
private readonly int _linkId;
|
||||
|
||||
public FakeLinkIdentityGenerator(int linkId)
|
||||
{
|
||||
_linkId = linkId;
|
||||
}
|
||||
|
||||
public int GenerateId(string link, string text)
|
||||
{
|
||||
return _linkId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,19 @@ namespace Spectre.Console.Testing
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterLazy(Type service, Func<object> factory)
|
||||
{
|
||||
if (factory is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(factory));
|
||||
}
|
||||
|
||||
if (!Instances.ContainsKey(service))
|
||||
{
|
||||
Instances.Add(service, new List<object> { factory() });
|
||||
}
|
||||
}
|
||||
|
||||
public ITypeResolver Build()
|
||||
{
|
||||
return _resolver;
|
||||
|
||||
@@ -7,6 +7,12 @@ dotnet_analyzer_diagnostic.category-StyleCop.CSharp.DocumentationRules.severity
|
||||
# CA1707: Identifiers should not contain underscores
|
||||
dotnet_diagnostic.CA1707.severity = none
|
||||
|
||||
# SA1600: Elements should be documented
|
||||
dotnet_diagnostic.SA1600.severity = none
|
||||
|
||||
# SA1601: Partial elements should be documented
|
||||
dotnet_diagnostic.SA1601.severity = none
|
||||
|
||||
# SA1200: Using directives should be placed correctly
|
||||
dotnet_diagnostic.SA1200.severity = none
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Tests
|
||||
{
|
||||
public static class Constants
|
||||
@@ -5,15 +7,15 @@ namespace Spectre.Console.Tests
|
||||
public static string[] VersionCommand { get; } =
|
||||
new[]
|
||||
{
|
||||
Spectre.Console.Cli.Internal.Constants.Commands.Branch,
|
||||
Spectre.Console.Cli.Internal.Constants.Commands.Version,
|
||||
CliConstants.Commands.Branch,
|
||||
CliConstants.Commands.Version,
|
||||
};
|
||||
|
||||
public static string[] XmlDocCommand { get; } =
|
||||
new[]
|
||||
{
|
||||
Spectre.Console.Cli.Internal.Constants.Commands.Branch,
|
||||
Spectre.Console.Cli.Internal.Constants.Commands.XmlDoc,
|
||||
CliConstants.Commands.Branch,
|
||||
CliConstants.Commands.XmlDoc,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
{
|
||||
public static class TestExceptions
|
||||
{
|
||||
[SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "<Pending>")]
|
||||
public static bool MethodThatThrows(int? number) => throw new InvalidOperationException("Throwing!");
|
||||
|
||||
[SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "<Pending>")]
|
||||
public static bool GenericMethodThatThrows<T0, T1, TRet>(int? number) => throw new InvalidOperationException("Throwing!");
|
||||
|
||||
public static void ThrowWithInnerException()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
@@ -6,7 +5,6 @@ namespace Spectre.Console.Tests.Data
|
||||
public class ArgumentVectorSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<Foos>")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public string[] Foo { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
@@ -6,18 +5,15 @@ namespace Spectre.Console.Tests.Data
|
||||
public class MultipleArgumentVectorSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<Foos>")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public string[] Foo { get; set; }
|
||||
|
||||
[CommandArgument(0, "<Bars>")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public string[] Bar { get; set; }
|
||||
}
|
||||
|
||||
public class MultipleArgumentVectorSpecifiedFirstSettings : CommandSettings
|
||||
{
|
||||
[CommandArgument(0, "<Foos>")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public string[] Foo { get; set; }
|
||||
|
||||
[CommandArgument(1, "<Bar>")]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Spectre.Console.Cli;
|
||||
|
||||
namespace Spectre.Console.Tests.Data
|
||||
@@ -6,11 +5,9 @@ namespace Spectre.Console.Tests.Data
|
||||
public class OptionVectorSettings : CommandSettings
|
||||
{
|
||||
[CommandOption("--foo")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public string[] Foo { get; set; }
|
||||
|
||||
[CommandOption("--bar")]
|
||||
[SuppressMessage("Performance", "CA1819:Properties should not return arrays")]
|
||||
public int[] Bar { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
Greeting
|
||||
Hello World
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
Number of fruits
|
||||
Apple 0
|
||||
Orange █████████████████████████████████████████████████ 54
|
||||
Banana ████████████████████████████ 33
|
||||
@@ -0,0 +1,4 @@
|
||||
[38;5;9m████████████████████████[0m[38;5;12m█████████████████[0m[38;5;2m█████████████[0m[38;5;11m███[0m[38;5;119m███[0m
|
||||
|
||||
[38;5;9m■[0m SCSS [38;5;8m37[0m [38;5;12m■[0m HTML [38;5;8m28.3[0m [38;5;2m■[0m C# [38;5;8m22.6[0m [38;5;11m■[0m JavaScript [38;5;8m6[0m
|
||||
[38;5;119m■[0m Ruby [38;5;8m6[0m [38;5;14m■[0m Shell [38;5;8m0.1[0m
|
||||
@@ -0,0 +1,3 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
■ SCSS 37 ■ HTML 28,3 ■ C# 22,6 ■ JavaScript 6
|
||||
■ Ruby 6 ■ Shell 0,1
|
||||
@@ -0,0 +1,2 @@
|
||||
████████████████████████████████████████████████████████████████████████████████
|
||||
■ SCSS 37 ■ HTML 28.3 ■ C# 22.6 ■ JavaScript 6 ■ Ruby 6 ■ Shell 0.1
|
||||
@@ -0,0 +1,4 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
|
||||
■ SCSS 37 ■ HTML 28.3 ■ C# 22.6 ■ JavaScript 6
|
||||
■ Ruby 6 ■ Shell 0.1
|
||||
@@ -0,0 +1,2 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
■ SCSS ■ HTML ■ C# ■ JavaScript ■ Ruby ■ Shell
|
||||
@@ -0,0 +1 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
@@ -0,0 +1,3 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
■ SCSS 37% ■ HTML 28,3% ■ C# 22,6% ■ JavaScript 6%
|
||||
■ Ruby 6% ■ Shell 0,1%
|
||||
@@ -0,0 +1,3 @@
|
||||
████████████████████████████████████████████████████████████
|
||||
■ SCSS 37 ■ HTML 28.3 ■ C# 22.6 ■ JavaScript 6
|
||||
■ Ruby 6 ■ Shell 0.1
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
foo ━━━ 0% -:--:-- ⣷
|
||||
bar ━━━ 0% -:--:-- ⣷
|
||||
baz ━━━ 0% -:--:-- ⣷
|
||||
foo ━━ 0% --:--:-- ⣷
|
||||
bar ━━ 0% --:--:-- ⣷
|
||||
baz ━━ 0% --:--:-- ⣷
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Favorite fruit? (******): ******
|
||||
@@ -19,7 +19,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="Shouldly" Version="4.0.3" />
|
||||
<PackageReference Include="Spectre.Verify.Extensions" Version="0.1.0" />
|
||||
<PackageReference Include="Spectre.Verify.Extensions" Version="0.3.0" />
|
||||
<PackageReference Include="Verify.Xunit" Version="9.0.0-beta.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
<ProjectConfiguration>
|
||||
<Settings>
|
||||
<IgnoredTests>
|
||||
<NamedTestSelector>
|
||||
<TestName>Spectre.Console.Tests.Unit.Cli.CommandAppTests+Parsing+UnknownCommand.Should_Return_Correct_Text_With_Suggestion_And_No_Arguments_When_Root_Command_Is_Unknown_And_Distance_Is_Small</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>Spectre.Console.Tests.Unit.Cli.CommandAppTests+Parsing+UnknownCommand.Should_Return_Correct_Text_With_Suggestion_When_Command_Followed_By_Argument_Is_Unknown_And_Distance_Is_Small</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>Spectre.Console.Tests.Unit.Cli.CommandAppTests+Parsing+UnknownCommand.Should_Return_Correct_Text_With_Suggestion_When_Root_Command_After_Argument_Is_Unknown_And_Distance_Is_Small</TestName>
|
||||
</NamedTestSelector>
|
||||
<NamedTestSelector>
|
||||
<TestName>Spectre.Console.Tests.Unit.Cli.CommandAppTests+Parsing+UnknownCommand.Should_Return_Correct_Text_With_Suggestion_When_Root_Command_Followed_By_Argument_Is_Unknown_And_Distance_Is_Small</TestName>
|
||||
</NamedTestSelector>
|
||||
</IgnoredTests>
|
||||
</Settings>
|
||||
<Settings />
|
||||
</ProjectConfiguration>
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Testing;
|
||||
using Xunit;
|
||||
@@ -8,14 +7,11 @@ namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public partial class AnsiConsoleTests
|
||||
{
|
||||
[SuppressMessage("Naming", "CA1724:Type names should not match namespaces")]
|
||||
public sealed class Markup
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("[yellow]Hello[/]", "[93mHello[0m")]
|
||||
[InlineData("[yellow]Hello [italic]World[/]![/]", "[93mHello [0m[3;93mWorld[0m[93m![0m")]
|
||||
[InlineData("[link=https://patriksvensson.se]Click to visit my blog[/]", "]8;id=1024;https://patriksvensson.se\\Click to visit my blog]8;;\\")]
|
||||
[InlineData("[link]https://patriksvensson.se[/]", "]8;id=1024;https://patriksvensson.se\\https://patriksvensson.se]8;;\\")]
|
||||
public void Should_Output_Expected_Ansi_For_Markup(string markup, string expected)
|
||||
{
|
||||
// Given
|
||||
@@ -28,6 +24,32 @@ namespace Spectre.Console.Tests.Unit
|
||||
console.Output.ShouldBe(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Output_Expected_Ansi_For_Link_With_Url_And_Text()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||
|
||||
// When
|
||||
console.Markup("[link=https://patriksvensson.se]Click to visit my blog[/]");
|
||||
|
||||
// Then
|
||||
console.Output.ShouldMatch("]8;id=[0-9]*;https:\\/\\/patriksvensson\\.se\\\\Click to visit my blog]8;;\\\\");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Output_Expected_Ansi_For_Link_With_Only_Url()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||
|
||||
// When
|
||||
console.Markup("[link]https://patriksvensson.se[/]");
|
||||
|
||||
// Then
|
||||
console.Output.ShouldMatch("]8;id=[0-9]*;https:\\/\\/patriksvensson\\.se\\\\https:\\/\\/patriksvensson\\.se]8;;\\\\");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("[yellow]Hello [[ World[/]", "[93mHello [ World[0m")]
|
||||
public void Should_Be_Able_To_Escape_Tags(string markup, string expected)
|
||||
|
||||
@@ -28,5 +28,24 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("Zero_Value")]
|
||||
public async Task Should_Render_Correctly_2()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
|
||||
// When
|
||||
console.Render(new BarChart()
|
||||
.Width(60)
|
||||
.Label("Number of fruits")
|
||||
.AddItem("Apple", 0)
|
||||
.AddItem("Orange", 54)
|
||||
.AddItem("Banana", 33));
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
150
src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs
Normal file
150
src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System.Threading.Tasks;
|
||||
using Spectre.Console.Testing;
|
||||
using Spectre.Verify.Extensions;
|
||||
using VerifyXunit;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
[UsesVerify]
|
||||
[ExpectationPath("Widgets/BreakdownChart")]
|
||||
public sealed class BreakdownChartTests
|
||||
{
|
||||
[Fact]
|
||||
[Expectation("Default")]
|
||||
public async Task Should_Render_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart();
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("Width")]
|
||||
public async Task Should_Render_With_Specific_Width()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart().Width(60);
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("TagFormat")]
|
||||
public async Task Should_Render_Correctly_With_Specific_Value_Formatter()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart()
|
||||
.Width(60)
|
||||
.Culture("sv-SE")
|
||||
.UseValueFormatter((v, c) => string.Format(c, "{0}%", v));
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("HideTags")]
|
||||
public async Task Should_Render_Correctly_Without_Tags()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart().Width(60).HideTags();
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("HideTagValues")]
|
||||
public async Task Should_Render_Correctly_Without_Tag_Values()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart().Width(60).HideTagValues();
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("Culture")]
|
||||
public async Task Should_Render_Correctly_With_Specific_Culture()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart().Width(60).Culture("sv-SE");
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("FullSize")]
|
||||
public async Task Should_Render_FullSize_Mode_Correctly()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
var chart = Fixture.GetChart().Width(60).FullSize();
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("Ansi")]
|
||||
public async Task Should_Render_Correct_Ansi()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeAnsiConsole(ColorSystem.EightBit, width: 80);
|
||||
var chart = Fixture.GetChart().Width(60).FullSize();
|
||||
|
||||
// When
|
||||
console.Render(chart);
|
||||
|
||||
// Then
|
||||
await Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
public static class Fixture
|
||||
{
|
||||
public static BreakdownChart GetChart()
|
||||
{
|
||||
return new BreakdownChart()
|
||||
.AddItem("SCSS", 37, Color.Red)
|
||||
.AddItem("HTML", 28.3, Color.Blue)
|
||||
.AddItem("C#", 22.6, Color.Green)
|
||||
.AddItem("JavaScript", 6, Color.Yellow)
|
||||
.AddItem("Ruby", 6, Color.LightGreen)
|
||||
.AddItem("Shell", 0.1, Color.Aqua);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,5 +71,19 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Then
|
||||
console.Output.ShouldBe(output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_not_fail_with_brackets_on_calls_without_args()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeAnsiConsole(ColorSystem.Standard, AnsiSupport.Yes);
|
||||
|
||||
// When
|
||||
console.MarkupLine("{");
|
||||
|
||||
// Then
|
||||
console.Output.NormalizeLineEndings()
|
||||
.ShouldBe("{\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Globalization;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class DownloadedColumnTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(0, 1, "0/1 byte")]
|
||||
[InlineData(37, 101, "37/101 bytes")]
|
||||
[InlineData(101, 101, "101 bytes")]
|
||||
[InlineData(512, 1024, "0.5/1.0 KB")]
|
||||
[InlineData(1024, 1024, "1.0 KB")]
|
||||
[InlineData(1024 * 512, 5 * 1024 * 1024, "0.5/5.0 MB")]
|
||||
[InlineData(5 * 1024 * 1024, 5 * 1024 * 1024, "5.0 MB")]
|
||||
public void Should_Return_Correct_Value(double value, double total, string expected)
|
||||
{
|
||||
// Given
|
||||
var fixture = new ProgressColumnFixture<DownloadedColumn>(value, total);
|
||||
fixture.Column.Culture = CultureInfo.InvariantCulture;
|
||||
|
||||
// When
|
||||
var result = fixture.Render();
|
||||
|
||||
// Then
|
||||
result.ShouldBe(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Spectre.Console.Rendering;
|
||||
using Spectre.Console.Testing;
|
||||
|
||||
namespace Spectre.Console.Tests.Unit
|
||||
{
|
||||
public sealed class ProgressColumnFixture<T>
|
||||
where T : ProgressColumn, new()
|
||||
{
|
||||
public T Column { get; }
|
||||
public ProgressTask Task { get; set; }
|
||||
|
||||
public ProgressColumnFixture(double completed, double total)
|
||||
{
|
||||
Column = new T();
|
||||
Task = new ProgressTask(1, "Foo", total);
|
||||
Task.Increment(completed);
|
||||
}
|
||||
|
||||
public string Render()
|
||||
{
|
||||
var console = new FakeConsole();
|
||||
var context = new RenderContext(Encoding.UTF8, false);
|
||||
console.Render(Column.Render(context, Task, TimeSpan.Zero));
|
||||
return console.Output;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,5 +115,111 @@ namespace Spectre.Console.Tests.Unit
|
||||
task.MaxValue.ShouldBe(20);
|
||||
task.Value.ShouldBe(20);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Setting_Value_Should_Override_Incremented_Value()
|
||||
{
|
||||
// Given
|
||||
var task = default(ProgressTask);
|
||||
var console = new FakeConsole();
|
||||
var progress = new Progress(console)
|
||||
.Columns(new[] { new ProgressBarColumn() })
|
||||
.AutoRefresh(false)
|
||||
.AutoClear(false);
|
||||
|
||||
// When
|
||||
progress.Start(ctx =>
|
||||
{
|
||||
task = ctx.AddTask("foo");
|
||||
task.Increment(50);
|
||||
task.Value = 20;
|
||||
});
|
||||
|
||||
// Then
|
||||
task.MaxValue.ShouldBe(100);
|
||||
task.Value.ShouldBe(20);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Setting_Value_To_MaxValue_Should_Finish_Task()
|
||||
{
|
||||
// Given
|
||||
var task = default(ProgressTask);
|
||||
var console = new FakeConsole();
|
||||
var progress = new Progress(console)
|
||||
.Columns(new[] { new ProgressBarColumn() })
|
||||
.AutoRefresh(false)
|
||||
.AutoClear(false);
|
||||
|
||||
// When
|
||||
progress.Start(ctx =>
|
||||
{
|
||||
task = ctx.AddTask("foo");
|
||||
task.Value = task.MaxValue;
|
||||
});
|
||||
|
||||
// Then
|
||||
task.IsFinished.ShouldBe(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Increment_Manually_Set_Value()
|
||||
{
|
||||
// Given
|
||||
var task = default(ProgressTask);
|
||||
var console = new FakeConsole();
|
||||
var progress = new Progress(console)
|
||||
.Columns(new[] { new ProgressBarColumn() })
|
||||
.AutoRefresh(false)
|
||||
.AutoClear(false);
|
||||
|
||||
// When
|
||||
progress.Start(ctx =>
|
||||
{
|
||||
task = ctx.AddTask("foo");
|
||||
task.Value = 50;
|
||||
task.Increment(10);
|
||||
});
|
||||
|
||||
// Then
|
||||
task.Value.ShouldBe(60);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Hide_Completed_Tasks()
|
||||
{
|
||||
// Given
|
||||
var taskFinished = default(ProgressTask);
|
||||
var taskInProgress1 = default(ProgressTask);
|
||||
var taskInProgress2 = default(ProgressTask);
|
||||
var console = new FakeAnsiConsole(ColorSystem.TrueColor, width: 10);
|
||||
|
||||
var progress = new Progress(console)
|
||||
.Columns(new[] { new ProgressBarColumn() })
|
||||
.AutoRefresh(false)
|
||||
.AutoClear(false)
|
||||
.HideCompleted(true);
|
||||
|
||||
// When
|
||||
progress.Start(ctx =>
|
||||
{
|
||||
taskInProgress1 = ctx.AddTask("foo");
|
||||
taskFinished = ctx.AddTask("bar");
|
||||
taskInProgress2 = ctx.AddTask("baz");
|
||||
taskInProgress2.Increment(20);
|
||||
taskFinished.Value = taskFinished.MaxValue;
|
||||
});
|
||||
|
||||
// Then
|
||||
console.Output
|
||||
.NormalizeLineEndings()
|
||||
.ShouldBe(
|
||||
"[?25l" + // Hide cursor
|
||||
" \n" + // top padding
|
||||
"[38;5;8m━━━━━━━━━━[0m\n" + // taskInProgress1
|
||||
"[38;5;11m━━[0m[38;5;8m━━━━━━━━[0m\n" + // taskInProgress2
|
||||
" \n" + // bottom padding
|
||||
"[?25h"); // show cursor
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,5 +200,23 @@ namespace Spectre.Console.Tests.Unit
|
||||
result.Item1.ShouldBe(2);
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Expectation("SecretDefaultValue")]
|
||||
public Task Should_Chose_Masked_Default_Value_If_Nothing_Is_Entered_And_Prompt_Is_Secret()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole();
|
||||
console.Input.PushKey(ConsoleKey.Enter);
|
||||
|
||||
// When
|
||||
console.Prompt(
|
||||
new TextPrompt<string>("Favorite fruit?")
|
||||
.Secret()
|
||||
.DefaultValue("Banana"));
|
||||
|
||||
// Then
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Shouldly;
|
||||
using Spectre.Console.Testing;
|
||||
using Spectre.Verify.Extensions;
|
||||
using VerifyXunit;
|
||||
@@ -56,5 +57,29 @@ namespace Spectre.Console.Tests.Unit
|
||||
// Then
|
||||
return Verifier.Verify(console.Output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Throw_If_Tree_Contains_Cycles()
|
||||
{
|
||||
// Given
|
||||
var console = new FakeConsole(width: 80);
|
||||
|
||||
var child2 = new TreeNode(new Text("child 2"));
|
||||
var child3 = new TreeNode(new Text("child 3"));
|
||||
var child1 = new TreeNode(new Text("child 1"));
|
||||
child1.AddNodes(child2, child3);
|
||||
var root = new TreeNode(new Text("Branch Node"));
|
||||
root.AddNodes(child1);
|
||||
child2.AddNode(root);
|
||||
|
||||
var tree = new Tree("root node");
|
||||
tree.AddNodes(root);
|
||||
|
||||
// When
|
||||
var result = Record.Exception(() => console.Render(tree));
|
||||
|
||||
// Then
|
||||
result.ShouldBeOfType<CircularTreeException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{E0E4
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trees", "..\examples\Console\Trees\Trees.csproj", "{CA7AF967-3FA5-4CB1-9564-740CF4527895}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "..\examples\Cli\Logging\Logging.csproj", "{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -426,6 +428,18 @@ Global
|
||||
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CA7AF967-3FA5-4CB1-9564-740CF4527895}.Release|x86.Build.0 = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -458,6 +472,7 @@ Global
|
||||
{E9C02C5A-710C-4A57-A008-E3EAC89305CC} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
|
||||
{F83CB4F1-95B8-45A4-A415-6DB5F8CA1E12} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
|
||||
{CA7AF967-3FA5-4CB1-9564-740CF4527895} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
|
||||
{33C7075A-DF97-44FC-8AB3-0CCFBA03341A} = {42792D7F-0BB6-4EE1-A314-8889305A4C48}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
|
||||
|
||||
2
src/Spectre.Console.sln.DotSettings
Normal file
2
src/Spectre.Console.sln.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">DO_NOT_SHOW</s:String></wpf:ResourceDictionary>
|
||||
@@ -38,10 +38,15 @@ namespace Spectre.Console
|
||||
/// Displays a prompt with two choices, yes or no.
|
||||
/// </summary>
|
||||
/// <param name="prompt">The prompt markup text.</param>
|
||||
/// <param name="defaultValue">Specifies the default answer.</param>
|
||||
/// <returns><c>true</c> if the user selected "yes", otherwise <c>false</c>.</returns>
|
||||
public static bool Confirm(string prompt)
|
||||
public static bool Confirm(string prompt, bool defaultValue = true)
|
||||
{
|
||||
return new ConfirmationPrompt(prompt).Show(Console);
|
||||
return new ConfirmationPrompt(prompt)
|
||||
{
|
||||
DefaultValue = defaultValue,
|
||||
}
|
||||
.Show(Console);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static void Record()
|
||||
{
|
||||
_recorder = new Recorder(_console.Value);
|
||||
if (_recorder == null)
|
||||
{
|
||||
_recorder = new Recorder(Console);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Spectre.Console.Internal;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
@@ -8,7 +7,9 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public static partial class AnsiConsole
|
||||
{
|
||||
private static readonly Lazy<IAnsiConsole> _console = new Lazy<IAnsiConsole>(() =>
|
||||
private static Recorder? _recorder;
|
||||
private static Lazy<IAnsiConsole> _console = new Lazy<IAnsiConsole>(
|
||||
() =>
|
||||
{
|
||||
var console = Create(new AnsiConsoleSettings
|
||||
{
|
||||
@@ -16,16 +17,33 @@ namespace Spectre.Console
|
||||
ColorSystem = ColorSystemSupport.Detect,
|
||||
Out = System.Console.Out,
|
||||
});
|
||||
|
||||
Created = true;
|
||||
return console;
|
||||
});
|
||||
|
||||
private static Recorder? _recorder;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying <see cref="IAnsiConsole"/>.
|
||||
/// Gets or sets the underlying <see cref="IAnsiConsole"/>.
|
||||
/// </summary>
|
||||
public static IAnsiConsole Console => _recorder ?? _console.Value;
|
||||
public static IAnsiConsole Console
|
||||
{
|
||||
get
|
||||
{
|
||||
return _recorder ?? _console.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_console = new Lazy<IAnsiConsole>(() => value);
|
||||
|
||||
if (_recorder != null)
|
||||
{
|
||||
// Recreate the recorder
|
||||
_recorder = _recorder.Clone(value);
|
||||
}
|
||||
|
||||
Created = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAnsiConsoleCursor"/>.
|
||||
@@ -33,25 +51,9 @@ namespace Spectre.Console
|
||||
public static IAnsiConsoleCursor Cursor => _recorder?.Cursor ?? _console.Value.Cursor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the console's capabilities.
|
||||
/// Gets the console profile.
|
||||
/// </summary>
|
||||
public static Capabilities Capabilities => Console.Capabilities;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the buffer width of the console.
|
||||
/// </summary>
|
||||
public static int Width
|
||||
{
|
||||
get => Console.Width;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the buffer height of the console.
|
||||
/// </summary>
|
||||
public static int Height
|
||||
{
|
||||
get => Console.Height;
|
||||
}
|
||||
public static Profile Profile => Console.Profile;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="IAnsiConsole"/> instance
|
||||
@@ -61,7 +63,8 @@ namespace Spectre.Console
|
||||
/// <returns>An <see cref="IAnsiConsole"/> instance.</returns>
|
||||
public static IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
{
|
||||
return BackendBuilder.Build(settings);
|
||||
var factory = new AnsiConsoleFactory();
|
||||
return factory.Create(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
105
src/Spectre.Console/AnsiConsoleFactory.cs
Normal file
105
src/Spectre.Console/AnsiConsoleFactory.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Spectre.Console.Enrichment;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory for creating an ANSI console.
|
||||
/// </summary>
|
||||
public sealed class AnsiConsoleFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an ANSI console.
|
||||
/// </summary>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <returns>An implementation of <see cref="IAnsiConsole"/>.</returns>
|
||||
public IAnsiConsole Create(AnsiConsoleSettings settings)
|
||||
{
|
||||
if (settings is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
var buffer = settings.Out ?? System.Console.Out;
|
||||
|
||||
// Detect if the terminal support ANSI or not
|
||||
var (supportsAnsi, legacyConsole) = DetectAnsi(settings, buffer);
|
||||
|
||||
// Use the provided encoding or fall back to UTF-8
|
||||
var encoding = buffer.IsStandardOut() || buffer.IsStandardError() ? System.Console.OutputEncoding : Encoding.UTF8;
|
||||
|
||||
// Get the color system
|
||||
var colorSystem = settings.ColorSystem == ColorSystemSupport.Detect
|
||||
? ColorSystemDetector.Detect(supportsAnsi)
|
||||
: (ColorSystem)settings.ColorSystem;
|
||||
|
||||
// Get whether or not we consider the terminal interactive
|
||||
var interactive = settings.Interactive == InteractionSupport.Yes;
|
||||
if (settings.Interactive == InteractionSupport.Detect)
|
||||
{
|
||||
interactive = Environment.UserInteractive;
|
||||
}
|
||||
|
||||
var profile = new Profile(buffer, encoding)
|
||||
{
|
||||
ColorSystem = colorSystem,
|
||||
};
|
||||
|
||||
profile.Capabilities.Ansi = supportsAnsi;
|
||||
profile.Capabilities.Links = supportsAnsi && !legacyConsole;
|
||||
profile.Capabilities.Legacy = legacyConsole;
|
||||
profile.Capabilities.Interactive = interactive;
|
||||
|
||||
// Enrich the profile
|
||||
ProfileEnricher.Enrich(
|
||||
profile,
|
||||
settings.Enrichment,
|
||||
settings.EnvironmentVariables);
|
||||
|
||||
return new AnsiConsoleFacade(profile);
|
||||
}
|
||||
|
||||
private static (bool Ansi, bool Legacy) DetectAnsi(AnsiConsoleSettings settings, System.IO.TextWriter buffer)
|
||||
{
|
||||
var supportsAnsi = settings.Ansi == AnsiSupport.Yes;
|
||||
var legacyConsole = false;
|
||||
|
||||
if (settings.Ansi == AnsiSupport.Detect)
|
||||
{
|
||||
(supportsAnsi, legacyConsole) = AnsiDetector.Detect(true);
|
||||
|
||||
// Check whether or not this is a legacy console from the existing instance (if any).
|
||||
// We need to do this because once we upgrade the console to support ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
// on Windows, there is no way of detecting whether or not we're running on a legacy console or not.
|
||||
if (AnsiConsole.Created && !legacyConsole && (buffer.IsStandardOut() || buffer.IsStandardError()) && AnsiConsole.Profile.Capabilities.Legacy)
|
||||
{
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buffer.IsStandardOut() || buffer.IsStandardError())
|
||||
{
|
||||
// Are we running on Windows?
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
// Not the first console we're creating?
|
||||
if (AnsiConsole.Created)
|
||||
{
|
||||
legacyConsole = AnsiConsole.Profile.Capabilities.Legacy;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try detecting whether or not this
|
||||
(_, legacyConsole) = AnsiDetector.Detect(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (supportsAnsi, legacyConsole);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Spectre.Console
|
||||
@@ -19,19 +20,33 @@ namespace Spectre.Console
|
||||
public ColorSystemSupport ColorSystem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or
|
||||
/// not the console is interactive.
|
||||
/// Gets or sets the out buffer.
|
||||
/// </summary>
|
||||
public TextWriter? Out { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the
|
||||
/// terminal is interactive or not.
|
||||
/// </summary>
|
||||
public InteractionSupport Interactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the link identity generator.
|
||||
/// Gets or sets the profile enrichments settings.
|
||||
/// </summary>
|
||||
public ILinkIdentityGenerator? LinkIdentityGenerator { get; set; }
|
||||
public ProfileEnrichment Enrichment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the out buffer.
|
||||
/// Gets or sets the environment variables.
|
||||
/// If not value is provided the default environment variables will be used.
|
||||
/// </summary>
|
||||
public TextWriter? Out { get; set; }
|
||||
public Dictionary<string, string>? EnvironmentVariables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AnsiConsoleSettings"/> class.
|
||||
/// </summary>
|
||||
public AnsiConsoleSettings()
|
||||
{
|
||||
Enrichment = new ProfileEnrichment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console
|
||||
{
|
||||
/// <summary>
|
||||
@@ -5,14 +7,16 @@ namespace Spectre.Console
|
||||
/// </summary>
|
||||
public sealed class Capabilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not
|
||||
/// the console supports Ansi.
|
||||
/// </summary>
|
||||
public bool SupportsAnsi { get; }
|
||||
private readonly Profile _profile;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not
|
||||
/// Gets or sets a value indicating whether or not
|
||||
/// the console supports Ansi.
|
||||
/// </summary>
|
||||
public bool Ansi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not
|
||||
/// the console support links.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
@@ -20,69 +24,53 @@ namespace Spectre.Console
|
||||
/// once we have more information about the terminal
|
||||
/// we're running inside.
|
||||
/// </remarks>
|
||||
public bool SupportLinks => SupportsAnsi && !LegacyConsole;
|
||||
public bool Links { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the color system.
|
||||
/// </summary>
|
||||
public ColorSystem ColorSystem { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not
|
||||
/// this is a legacy console (cmd.exe).
|
||||
/// Gets or sets a value indicating whether or not
|
||||
/// this is a legacy console (cmd.exe) on an OS
|
||||
/// prior to Windows 10.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only relevant when running on Microsoft Windows.
|
||||
/// </remarks>
|
||||
public bool LegacyConsole { get; }
|
||||
public bool Legacy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not the console supports interaction.
|
||||
/// Gets a value indicating whether console output
|
||||
/// has been redirected.
|
||||
/// </summary>
|
||||
public bool SupportsInteraction { get; set; }
|
||||
public bool Tty
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_profile.Out.IsStandardOut())
|
||||
{
|
||||
return System.Console.IsOutputRedirected;
|
||||
}
|
||||
|
||||
if (_profile.Out.IsStandardError())
|
||||
{
|
||||
return System.Console.IsErrorRedirected;
|
||||
}
|
||||
|
||||
// Not stdout, so must be a TTY.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether
|
||||
/// or not the console supports interaction.
|
||||
/// </summary>
|
||||
public bool Interactive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Capabilities"/> class.
|
||||
/// </summary>
|
||||
/// <param name="supportsAnsi">Whether or not ANSI escape sequences are supported.</param>
|
||||
/// <param name="colorSystem">The color system that is supported.</param>
|
||||
/// <param name="legacyConsole">Whether or not this is a legacy console.</param>
|
||||
/// <param name="supportsInteraction">Whether or not the console supports interaction.</param>
|
||||
public Capabilities(bool supportsAnsi, ColorSystem colorSystem, bool legacyConsole, bool supportsInteraction)
|
||||
internal Capabilities(Profile profile)
|
||||
{
|
||||
SupportsAnsi = supportsAnsi;
|
||||
ColorSystem = colorSystem;
|
||||
LegacyConsole = legacyConsole;
|
||||
SupportsInteraction = supportsInteraction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the current capabilities supports
|
||||
/// the specified color system.
|
||||
/// </summary>
|
||||
/// <param name="colorSystem">The color system to check.</param>
|
||||
/// <returns><c>true</c> if the color system is supported, otherwise <c>false</c>.</returns>
|
||||
public bool Supports(ColorSystem colorSystem)
|
||||
{
|
||||
return (int)colorSystem <= (int)ColorSystem;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
var supportsAnsi = SupportsAnsi ? "Yes" : "No";
|
||||
var legacyConsole = LegacyConsole ? "Legacy" : "Modern";
|
||||
var bits = ColorSystem switch
|
||||
{
|
||||
ColorSystem.NoColors => "1 bit",
|
||||
ColorSystem.Legacy => "3 bits",
|
||||
ColorSystem.Standard => "4 bits",
|
||||
ColorSystem.EightBit => "8 bits",
|
||||
ColorSystem.TrueColor => "24 bits",
|
||||
_ => "?",
|
||||
};
|
||||
|
||||
return $"ANSI={supportsAnsi}, Colors={ColorSystem}, Kind={legacyConsole} ({bits})";
|
||||
_profile = profile ?? throw new ArgumentNullException(nameof(profile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
@@ -7,7 +6,6 @@ namespace Spectre.Console.Cli
|
||||
/// Represents case sensitivity.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
[SuppressMessage("Naming", "CA1714:Flags enums should have plural names")]
|
||||
public enum CaseSensitivity
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
@@ -74,11 +73,11 @@ namespace Spectre.Console.Cli
|
||||
if (!_executed)
|
||||
{
|
||||
// Add built-in (hidden) commands.
|
||||
_configurator.AddBranch(Constants.Commands.Branch, cli =>
|
||||
_configurator.AddBranch(CliConstants.Commands.Branch, cli =>
|
||||
{
|
||||
cli.HideBranch();
|
||||
cli.AddCommand<VersionCommand>(Constants.Commands.Version);
|
||||
cli.AddCommand<XmlDocCommand>(Constants.Commands.XmlDoc);
|
||||
cli.AddCommand<VersionCommand>(CliConstants.Commands.Version);
|
||||
cli.AddCommand<XmlDocCommand>(CliConstants.Commands.XmlDoc);
|
||||
});
|
||||
|
||||
_executed = true;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
@@ -33,7 +32,7 @@ namespace Spectre.Console.Cli
|
||||
|
||||
internal static CommandRuntimeException MissingRequiredArgument(CommandTree node, CommandArgument argument)
|
||||
{
|
||||
if (node.Command.Name == Constants.DefaultCommandName)
|
||||
if (node.Command.Name == CliConstants.DefaultCommandName)
|
||||
{
|
||||
return new CommandRuntimeException($"Missing required argument '{argument.Value}'.");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Globalization;
|
||||
using Spectre.Console.Cli.Internal;
|
||||
using Spectre.Console.Rendering;
|
||||
|
||||
namespace Spectre.Console.Cli
|
||||
|
||||
@@ -25,6 +25,23 @@ namespace Spectre.Console.Cli
|
||||
return configurator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the auto-detected version of the application.
|
||||
/// </summary>
|
||||
/// <param name="configurator">The configurator.</param>
|
||||
/// <param name="version">The version of application.</param>
|
||||
/// <returns>A configurator that can be used to configure the application further.</returns>
|
||||
public static IConfigurator SetApplicationVersion(this IConfigurator configurator, string version)
|
||||
{
|
||||
if (configurator == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configurator));
|
||||
}
|
||||
|
||||
configurator.Settings.ApplicationVersion = version;
|
||||
return configurator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the console.
|
||||
/// </summary>
|
||||
|
||||
@@ -10,6 +10,11 @@ namespace Spectre.Console.Cli
|
||||
/// </summary>
|
||||
string? ApplicationName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application version (use it to override auto-detected value).
|
||||
/// </summary>
|
||||
string? ApplicationVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IAnsiConsole"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -21,6 +21,13 @@ namespace Spectre.Console.Cli
|
||||
/// <param name="implementation">The implementation.</param>
|
||||
void RegisterInstance(Type service, object implementation);
|
||||
|
||||
/// <summary>
|
||||
/// Registers the specified instance lazily.
|
||||
/// </summary>
|
||||
/// <param name="service">The service.</param>
|
||||
/// <param name="factory">The factory that creates the implementation.</param>
|
||||
void RegisterLazy(Type service, Func<object> factory);
|
||||
|
||||
/// <summary>
|
||||
/// Builds the type resolver representing the registrations
|
||||
/// specified in the current instance.
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal static class CommandConstructorBinder
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal static class CommandPropertyBinder
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal sealed class CommandValueBinder
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal sealed class CommandValueLookup : IEnumerable<(CommandParameter Parameter, object? Value)>
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal static class CommandValueResolver
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
/// <summary>
|
||||
/// Representation of a multi map.
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
[SuppressMessage("Performance", "CA1812: Avoid uninstantiated internal classes")]
|
||||
internal sealed class MultiMap<TKey, TValue> : IMultiMap, ILookup<TKey, TValue>, IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal static class CommandBinder
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal sealed class CommandExecutor
|
||||
{
|
||||
@@ -24,7 +24,7 @@ namespace Spectre.Console.Cli.Internal
|
||||
}
|
||||
|
||||
_registrar.RegisterInstance(typeof(IConfiguration), configuration);
|
||||
_registrar.RegisterInstance(typeof(IAnsiConsole), configuration.Settings.Console.GetConsole());
|
||||
_registrar.RegisterLazy(typeof(IAnsiConsole), () => configuration.Settings.Console.GetConsole());
|
||||
|
||||
// Create the command model.
|
||||
var model = CommandModelBuilder.Build(configuration);
|
||||
@@ -44,7 +44,7 @@ namespace Spectre.Console.Cli.Internal
|
||||
firstArgument.Equals("-v", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var console = configuration.Settings.Console.GetConsole();
|
||||
console.WriteLine(VersionHelper.GetVersion(Assembly.GetEntryAssembly()));
|
||||
console.WriteLine(ResolveApplicationVersion(configuration));
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,13 @@ namespace Spectre.Console.Cli.Internal
|
||||
return Execute(leaf, parsedResult.Tree, context, resolver, configuration);
|
||||
}
|
||||
|
||||
private static string ResolveApplicationVersion(IConfiguration configuration)
|
||||
{
|
||||
return
|
||||
configuration.Settings.ApplicationVersion ?? // potential override
|
||||
VersionHelper.GetVersion(Assembly.GetEntryAssembly());
|
||||
}
|
||||
|
||||
private static Task<int> Execute(
|
||||
CommandTree leaf,
|
||||
CommandTree tree,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Spectre.Console.Cli.Internal
|
||||
namespace Spectre.Console.Cli
|
||||
{
|
||||
internal enum CommandPart
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user