Skip to content

Commit 6837b8f

Browse files
adamsitnikMike McLaughlin
andauthored
Update System.CommandLine version (#5217)
I am currently working on updating all the repos that are part of VMR to latest version of System.CommandLine. To tell the long story short, we want to release new S.CL, but also remove some parts like System.CommandLine.Rendering. I am pretty confident about my changes related to all the tools (first commit), but Microsoft.Diagnostics.DebugServices.Implementation work (2nd commit) will most likely need more work from my side. Since I am about to start my weekend I am opening this PR to at least get some initial feedback about the direction (so I know what to do on Monday). --------- Co-authored-by: Mike McLaughlin <mikem@microsoft.com>
1 parent ca29086 commit 6837b8f

38 files changed

+1228
-1118
lines changed

NuGet.config

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
<add key="dotnet10-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json" />
1616
<add key="dotnet9" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json" />
1717
<add key="dotnet9-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9-transport/nuget/v3/index.json" />
18-
<!-- Need this for the old version of System.CommandLine we use -->
19-
<add key="dotnet5" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json" />
18+
<!-- Need this for System.CommandLine -->
19+
<add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
2020
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
2121
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
2222
<add key="dotnet-diagnostics-tests" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-diagnostics-tests/nuget/v3/index.json" />

eng/Versions.props

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
<MicrosoftExtensionsLoggingConsoleVersion>6.0.0</MicrosoftExtensionsLoggingConsoleVersion>
4646
<!-- Need version that understands UseAppFilters sentinel. -->
4747
<MicrosoftExtensionsLoggingEventSourceVersion>5.0.1</MicrosoftExtensionsLoggingEventSourceVersion>
48-
<SystemCommandLineVersion>2.0.0-beta1.20468.1</SystemCommandLineVersion>
49-
<SystemCommandLineRenderingVersion>2.0.0-beta1.20074.1</SystemCommandLineRenderingVersion>
48+
<SystemCommandLineVersion>2.0.0-beta4.25072.1</SystemCommandLineVersion>
5049
<SystemComponentModelAnnotationsVersion>5.0.0</SystemComponentModelAnnotationsVersion>
5150
<SystemBuffersVersion>4.5.1</SystemBuffersVersion>
5251
<SystemMemoryVersion>4.5.5</SystemMemoryVersion>

src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs

Lines changed: 72 additions & 133 deletions
Large diffs are not rendered by default.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text;
5+
6+
namespace System.CommandLine
7+
{
8+
// class copied from https://raw.githubusercontent.com/dotnet/command-line-api/060374e56c1b2e741b6525ca8417006efb54fbd7/src/System.CommandLine.DragonFruit/StringExtensions.cs
9+
internal static class StringExtensions
10+
{
11+
public static string ToKebabCase(this string value)
12+
{
13+
if (string.IsNullOrEmpty(value))
14+
{
15+
return value;
16+
}
17+
18+
StringBuilder sb = new();
19+
int i = 0;
20+
bool addDash = false;
21+
22+
// handles beginning of string, breaks on first letter or digit. addDash might be better named "canAddDash"
23+
for (; i < value.Length; i++)
24+
{
25+
char ch = value[i];
26+
if (char.IsLetterOrDigit(ch))
27+
{
28+
addDash = !char.IsUpper(ch);
29+
sb.Append(char.ToLowerInvariant(ch));
30+
i++;
31+
break;
32+
}
33+
}
34+
35+
// reusing i, start at the same place
36+
for (; i < value.Length; i++)
37+
{
38+
char ch = value[i];
39+
if (char.IsUpper(ch))
40+
{
41+
if (addDash)
42+
{
43+
addDash = false;
44+
sb.Append('-');
45+
}
46+
47+
sb.Append(char.ToLowerInvariant(ch));
48+
}
49+
else if (char.IsLetterOrDigit(ch))
50+
{
51+
addDash = true;
52+
sb.Append(ch);
53+
}
54+
else //this coverts all non letter/digits to dash - specifically periods and underscores. Is this needed?
55+
{
56+
addDash = false;
57+
sb.Append('-');
58+
}
59+
}
60+
61+
return sb.ToString();
62+
}
63+
}
64+
}

src/SOS/SOS.UnitTests/Scripts/DumpGen.script

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ VERIFY: invalid is not a supported generation
1717

1818
!IFDEF:LLDB
1919
EXTCOMMAND_FAIL: dumpgen gen0 -mt
20-
VERIFY: Required argument missing for option: -mt
20+
VERIFY: Required argument missing for option: '-mt'.
2121

2222
EXTCOMMAND_FAIL: dumpgen gen1 -mt zzzzz
2323
VERIFY: Hexadecimal address expected for -mt option

src/Tools/Common/CommandExtensions.cs

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/Tools/Common/Commands/ProcessStatus.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,28 @@
44
using System;
55
using System.Collections.Generic;
66
using System.CommandLine;
7-
using System.CommandLine.Binding;
8-
using System.CommandLine.IO;
97
using System.ComponentModel;
108
using System.Diagnostics;
119
using System.IO;
1210
using System.Linq;
1311
using System.Runtime.InteropServices;
1412
using System.Text;
13+
using System.Threading.Tasks;
1514
using Microsoft.Diagnostics.NETCore.Client;
16-
using Microsoft.Internal.Common.Utils;
1715
using Microsoft.Internal.Common;
16+
using Microsoft.Internal.Common.Utils;
1817
using Process = System.Diagnostics.Process;
1918

2019
namespace Microsoft.Internal.Common.Commands
2120
{
2221
public class ProcessStatusCommandHandler
2322
{
24-
public static Command ProcessStatusCommand(string description) =>
25-
new(name: "ps", description)
26-
{
27-
HandlerDescriptor.FromDelegate((ProcessStatusDelegate)ProcessStatus).GetCommandHandler()
28-
};
29-
30-
private delegate void ProcessStatusDelegate(IConsole console);
23+
public static Command ProcessStatusCommand(string description)
24+
{
25+
Command statusCommand = new(name: "ps", description);
26+
statusCommand.SetAction((parseResult, ct) => Task.FromResult(ProcessStatus(parseResult.Configuration.Output, parseResult.Configuration.Error)));
27+
return statusCommand;
28+
}
3129

3230
private static void MakeFixedWidth(string text, int width, StringBuilder sb, bool leftPad = false, bool truncateFront = false)
3331
{
@@ -76,7 +74,7 @@ private struct ProcessDetails
7674
/// <summary>
7775
/// Print the current list of available .NET core processes for diagnosis, their statuses and the command line arguments that are passed to them.
7876
/// </summary>
79-
public static void ProcessStatus(IConsole console)
77+
public static int ProcessStatus(TextWriter stdOut, TextWriter stdError)
8078
{
8179
int GetColumnWidth(IEnumerable<int> fieldWidths)
8280
{
@@ -170,11 +168,13 @@ void FormatTableRows(List<ProcessDetails> rows, StringBuilder tableText)
170168
}
171169
}
172170
FormatTableRows(printInfo, sb);
173-
console.Out.WriteLine(sb.ToString());
171+
stdOut.WriteLine(sb.ToString());
172+
return 0;
174173
}
175174
catch (Exception ex)
176175
{
177-
console.Out.WriteLine(ex.ToString());
176+
stdError.WriteLine(ex.ToString());
177+
return 1;
178178
}
179179
}
180180

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.InteropServices;
5+
6+
namespace System.CommandLine.Rendering
7+
{
8+
internal static partial class Interop
9+
{
10+
public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
11+
12+
public const uint ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200;
13+
14+
public const uint DISABLE_NEWLINE_AUTO_RETURN = 0x0008;
15+
16+
public const int STD_OUTPUT_HANDLE = -11;
17+
18+
public const int STD_INPUT_HANDLE = -10;
19+
20+
[LibraryImport("kernel32.dll")]
21+
[return: MarshalAs(UnmanagedType.Bool)]
22+
public static partial bool GetConsoleMode(IntPtr handle, out uint mode);
23+
24+
[LibraryImport("kernel32.dll")]
25+
public static partial uint GetLastError();
26+
27+
[LibraryImport("kernel32.dll")]
28+
[return: MarshalAs(UnmanagedType.Bool)]
29+
public static partial bool SetConsoleMode(IntPtr handle, uint mode);
30+
31+
[LibraryImport("kernel32.dll", SetLastError = true)]
32+
public static partial IntPtr GetStdHandle(int handle);
33+
}
34+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Runtime.InteropServices;
5+
using static System.CommandLine.Rendering.Interop;
6+
7+
namespace System.CommandLine.Rendering
8+
{
9+
/// <summary>
10+
/// This file is a copy of https://github.com/dotnet/command-line-api/blob/060374e56c1b2e741b6525ca8417006efb54fbd7/src/System.CommandLine.Rendering/Interop.Windows.cs
11+
/// which is no longer supported.
12+
/// </summary>
13+
public sealed class VirtualTerminalMode : IDisposable
14+
{
15+
private readonly IntPtr _stdOutHandle;
16+
private readonly IntPtr _stdInHandle;
17+
private readonly uint _originalOutputMode;
18+
private readonly uint _originalInputMode;
19+
20+
private VirtualTerminalMode(bool isEnabled)
21+
{
22+
IsEnabled = isEnabled;
23+
GC.SuppressFinalize(this); // ctor used only on Unix, where there is nothing to cleanup
24+
}
25+
26+
private VirtualTerminalMode(
27+
IntPtr stdOutHandle,
28+
uint originalOutputMode,
29+
IntPtr stdInHandle,
30+
uint originalInputMode)
31+
{
32+
_stdOutHandle = stdOutHandle;
33+
_originalOutputMode = originalOutputMode;
34+
_stdInHandle = stdInHandle;
35+
_originalInputMode = originalInputMode;
36+
}
37+
38+
public bool IsEnabled { get; }
39+
40+
public static VirtualTerminalMode TryEnable()
41+
{
42+
if (OperatingSystem.IsWindows())
43+
{
44+
IntPtr stdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
45+
IntPtr stdInHandle = GetStdHandle(STD_INPUT_HANDLE);
46+
47+
if (!GetConsoleMode(stdOutHandle, out uint originalOutputMode))
48+
{
49+
return null;
50+
}
51+
52+
if (!GetConsoleMode(stdInHandle, out uint originalInputMode))
53+
{
54+
return null;
55+
}
56+
57+
uint requestedOutputMode = originalOutputMode |
58+
ENABLE_VIRTUAL_TERMINAL_PROCESSING |
59+
DISABLE_NEWLINE_AUTO_RETURN;
60+
61+
if (!SetConsoleMode(stdOutHandle, requestedOutputMode))
62+
{
63+
return null;
64+
}
65+
66+
return new VirtualTerminalMode(stdOutHandle,
67+
originalOutputMode,
68+
stdInHandle,
69+
originalInputMode);
70+
}
71+
else
72+
{
73+
string terminalName = Environment.GetEnvironmentVariable("TERM");
74+
75+
bool isXterm = !string.IsNullOrEmpty(terminalName)
76+
&& terminalName.StartsWith("xterm", StringComparison.OrdinalIgnoreCase);
77+
78+
// TODO: Is this a reasonable default?
79+
return new VirtualTerminalMode(isXterm);
80+
}
81+
}
82+
83+
private void RestoreConsoleMode()
84+
{
85+
if (IsEnabled)
86+
{
87+
if (_stdOutHandle != IntPtr.Zero)
88+
{
89+
SetConsoleMode(_stdOutHandle, _originalOutputMode);
90+
}
91+
}
92+
}
93+
94+
public void Dispose()
95+
{
96+
RestoreConsoleMode();
97+
GC.SuppressFinalize(this);
98+
}
99+
100+
~VirtualTerminalMode()
101+
{
102+
RestoreConsoleMode();
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)