Skip to content

Commit cbedfa2

Browse files
committed
Add IConsole, IReporter, DebugHelper, DotNetCliContext, and a few other APIs
1 parent 4afc7b7 commit cbedfa2

File tree

9 files changed

+268
-36
lines changed

9 files changed

+268
-36
lines changed

CommandLineUtils.sln

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,47 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26124.0
3+
VisualStudioVersion = 15.0.26730.12
54
MinimumVisualStudioVersion = 15.0.26124.0
65
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{95D4B35E-0A21-4D64-8BAF-27DD6C019FC5}"
76
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McMaster.Extensions.CommandLineUtils", "src\CommandLineUtils\McMaster.Extensions.CommandLineUtils.csproj", "{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}"
7+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "McMaster.Extensions.CommandLineUtils", "src\CommandLineUtils\McMaster.Extensions.CommandLineUtils.csproj", "{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}"
98
EndProject
109
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C4842A1B-019E-40FF-A396-CF5AFDE8FA54}"
1110
EndProject
12-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "McMaster.Extensions.CommandLineUtils.Tests", "test\CommandLineUtils.Tests\McMaster.Extensions.CommandLineUtils.Tests.csproj", "{1258544C-1FDE-4810-9A1B-189A925E9B45}"
11+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "McMaster.Extensions.CommandLineUtils.Tests", "test\CommandLineUtils.Tests\McMaster.Extensions.CommandLineUtils.Tests.csproj", "{1258544C-1FDE-4810-9A1B-189A925E9B45}"
1312
EndProject
1413
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{60B279C6-091B-4F3E-B21F-D71001C94660}"
1514
EndProject
16-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "samples\HelloWorld\HelloWorld.csproj", "{71521E54-158D-45D7-8746-4905E6B3EB21}"
15+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "samples\HelloWorld\HelloWorld.csproj", "{71521E54-158D-45D7-8746-4905E6B3EB21}"
1716
EndProject
1817
Global
1918
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2019
Debug|Any CPU = Debug|Any CPU
21-
Debug|x64 = Debug|x64
22-
Debug|x86 = Debug|x86
2320
Release|Any CPU = Release|Any CPU
24-
Release|x64 = Release|x64
25-
Release|x86 = Release|x86
26-
EndGlobalSection
27-
GlobalSection(SolutionProperties) = preSolution
28-
HideSolutionNode = FALSE
2921
EndGlobalSection
3022
GlobalSection(ProjectConfigurationPlatforms) = postSolution
3123
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3224
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
33-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|x64.ActiveCfg = Debug|x64
34-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|x64.Build.0 = Debug|x64
35-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|x86.ActiveCfg = Debug|x86
36-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Debug|x86.Build.0 = Debug|x86
3725
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
3826
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|Any CPU.Build.0 = Release|Any CPU
39-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|x64.ActiveCfg = Release|x64
40-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|x64.Build.0 = Release|x64
41-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|x86.ActiveCfg = Release|x86
42-
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}.Release|x86.Build.0 = Release|x86
4327
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4428
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|Any CPU.Build.0 = Debug|Any CPU
45-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|x64.ActiveCfg = Debug|x64
46-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|x64.Build.0 = Debug|x64
47-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|x86.ActiveCfg = Debug|x86
48-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Debug|x86.Build.0 = Debug|x86
4929
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|Any CPU.ActiveCfg = Release|Any CPU
5030
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|Any CPU.Build.0 = Release|Any CPU
51-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|x64.ActiveCfg = Release|x64
52-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|x64.Build.0 = Release|x64
53-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|x86.ActiveCfg = Release|x86
54-
{1258544C-1FDE-4810-9A1B-189A925E9B45}.Release|x86.Build.0 = Release|x86
5531
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
5632
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|Any CPU.Build.0 = Debug|Any CPU
57-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|x64.ActiveCfg = Debug|x64
58-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|x64.Build.0 = Debug|x64
59-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|x86.ActiveCfg = Debug|x86
60-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Debug|x86.Build.0 = Debug|x86
6133
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|Any CPU.ActiveCfg = Release|Any CPU
6234
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|Any CPU.Build.0 = Release|Any CPU
63-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|x64.ActiveCfg = Release|x64
64-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|x64.Build.0 = Release|x64
65-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|x86.ActiveCfg = Release|x86
66-
{71521E54-158D-45D7-8746-4905E6B3EB21}.Release|x86.Build.0 = Release|x86
35+
EndGlobalSection
36+
GlobalSection(SolutionProperties) = preSolution
37+
HideSolutionNode = FALSE
6738
EndGlobalSection
6839
GlobalSection(NestedProjects) = preSolution
6940
{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E} = {95D4B35E-0A21-4D64-8BAF-27DD6C019FC5}
7041
{1258544C-1FDE-4810-9A1B-189A925E9B45} = {C4842A1B-019E-40FF-A396-CF5AFDE8FA54}
7142
{71521E54-158D-45D7-8746-4905E6B3EB21} = {60B279C6-091B-4F3E-B21F-D71001C94660}
7243
EndGlobalSection
44+
GlobalSection(ExtensibilityGlobals) = postSolution
45+
SolutionGuid = {55FD25E0-565D-49F9-9370-28DA7196E539}
46+
EndGlobalSection
7347
EndGlobal
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Reflection;
6+
7+
namespace McMaster.Extensions.CommandLineUtils
8+
{
9+
public static class CommandLineApplicationExtensions
10+
{
11+
public static CommandOption HelpOption(this CommandLineApplication app)
12+
=> app.HelpOption("-?|-h|--help");
13+
14+
public static CommandOption VerboseOption(this CommandLineApplication app)
15+
=> app.Option("-v|--verbose", "Show verbose output", CommandOptionType.NoValue, inherited: true);
16+
17+
public static void OnExecute(this CommandLineApplication app, Action action)
18+
=> app.OnExecute(() =>
19+
{
20+
action();
21+
return 0;
22+
});
23+
24+
public static void VersionOptionFromAssemblyAttributes(this CommandLineApplication app, Assembly assembly)
25+
=> app.VersionOption("--version", GetInformationalVersion(assembly));
26+
27+
private static string GetInformationalVersion(Assembly assembly)
28+
{
29+
var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
30+
31+
var versionAttribute = attribute == null
32+
? assembly.GetName().Version.ToString()
33+
: attribute.InformationalVersion;
34+
35+
return versionAttribute;
36+
}
37+
}
38+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.IO;
6+
7+
namespace McMaster.Extensions.CommandLineUtils
8+
{
9+
public class ConsoleReporter : IReporter
10+
{
11+
private object _writeLock = new object();
12+
13+
public ConsoleReporter(IConsole console)
14+
: this(console, verbose: false, quiet: false)
15+
{ }
16+
17+
public ConsoleReporter(IConsole console, bool verbose, bool quiet)
18+
{
19+
Console = console ?? throw new ArgumentNullException(nameof(console));
20+
IsVerbose = verbose;
21+
IsQuiet = quiet;
22+
}
23+
24+
protected IConsole Console { get; }
25+
public bool IsVerbose { get; set; }
26+
public bool IsQuiet { get; set; }
27+
28+
protected virtual void WriteLine(TextWriter writer, string message, ConsoleColor? color)
29+
{
30+
lock (_writeLock)
31+
{
32+
if (color.HasValue)
33+
{
34+
Console.ForegroundColor = color.Value;
35+
}
36+
37+
writer.WriteLine(message);
38+
39+
if (color.HasValue)
40+
{
41+
Console.ResetColor();
42+
}
43+
}
44+
}
45+
46+
public virtual void Error(string message)
47+
=> WriteLine(Console.Error, message, ConsoleColor.Red);
48+
public virtual void Warn(string message)
49+
=> WriteLine(Console.Out, message, ConsoleColor.Yellow);
50+
51+
public virtual void Output(string message)
52+
{
53+
if (IsQuiet)
54+
{
55+
return;
56+
}
57+
WriteLine(Console.Out, message, color: null);
58+
}
59+
60+
public virtual void Verbose(string message)
61+
{
62+
if (!IsVerbose)
63+
{
64+
return;
65+
}
66+
67+
WriteLine(Console.Out, message, ConsoleColor.DarkGray);
68+
}
69+
}
70+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.IO;
6+
7+
namespace McMaster.Extensions.CommandLineUtils
8+
{
9+
public interface IConsole
10+
{
11+
event ConsoleCancelEventHandler CancelKeyPress;
12+
TextWriter Out { get; }
13+
TextWriter Error { get; }
14+
TextReader In { get; }
15+
bool IsInputRedirected { get; }
16+
bool IsOutputRedirected { get; }
17+
bool IsErrorRedirected { get; }
18+
ConsoleColor ForegroundColor { get; set; }
19+
void ResetColor();
20+
}
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace McMaster.Extensions.CommandLineUtils
5+
{
6+
public interface IReporter
7+
{
8+
void Verbose(string message);
9+
void Output(string message);
10+
void Warn(string message);
11+
void Error(string message);
12+
}
13+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace McMaster.Extensions.CommandLineUtils
5+
{
6+
public class NullReporter : IReporter
7+
{
8+
private NullReporter()
9+
{ }
10+
11+
public static IReporter Singleton { get; } = new NullReporter();
12+
13+
public void Verbose(string message)
14+
{ }
15+
16+
public void Output(string message)
17+
{ }
18+
19+
public void Warn(string message)
20+
{ }
21+
22+
public void Error(string message)
23+
{ }
24+
}
25+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.IO;
6+
7+
namespace McMaster.Extensions.CommandLineUtils
8+
{
9+
public class PhysicalConsole : IConsole
10+
{
11+
public static IConsole Singleton { get; } = new PhysicalConsole();
12+
13+
public event ConsoleCancelEventHandler CancelKeyPress
14+
{
15+
add => Console.CancelKeyPress += value;
16+
remove => Console.CancelKeyPress -= value;
17+
}
18+
19+
public TextWriter Error => Console.Error;
20+
public TextReader In => Console.In;
21+
public TextWriter Out => Console.Out;
22+
public bool IsInputRedirected => Console.IsInputRedirected;
23+
public bool IsOutputRedirected => Console.IsOutputRedirected;
24+
public bool IsErrorRedirected => Console.IsErrorRedirected;
25+
public ConsoleColor ForegroundColor
26+
{
27+
get => Console.ForegroundColor;
28+
set => Console.ForegroundColor = value;
29+
}
30+
31+
public void ResetColor() => Console.ResetColor();
32+
}
33+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using System.Threading;
8+
9+
namespace McMaster.Extensions.CommandLineUtils
10+
{
11+
/// <summary>
12+
/// Helps handle debug command-line arguments.
13+
/// </summary>
14+
public static class DebugHelper
15+
{
16+
/// <summary>
17+
/// Pauses the application for the debugger when '--debug' is passed in.
18+
/// </summary>
19+
/// <param name="args">The command line arguments</param>
20+
public static void HandleDebugSwitch(ref string[] args)
21+
{
22+
if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase))
23+
{
24+
args = args.Skip(1).ToArray();
25+
Console.WriteLine("Waiting for debugger to attach.");
26+
Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}");
27+
Debugger.Launch();
28+
while (Debugger.IsAttached)
29+
{
30+
Thread.Sleep(TimeSpan.MaxValue);
31+
}
32+
}
33+
}
34+
}
35+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
6+
namespace McMaster.Extensions.CommandLineUtils
7+
{
8+
/// <summary>
9+
/// APIs related to .NET Core CLI.
10+
/// </summary>
11+
public static class DotNetCliContext
12+
{
13+
/// <summary>
14+
/// dotnet --verbose subcommand
15+
/// </summary>
16+
/// <returns></returns>
17+
public static bool IsGlobalVerbose()
18+
{
19+
bool.TryParse(Environment.GetEnvironmentVariable("DOTNET_CLI_CONTEXT_VERBOSE"), out bool globalVerbose);
20+
return globalVerbose;
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)