-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathFormatHelper.cs
More file actions
88 lines (73 loc) · 3.29 KB
/
FormatHelper.cs
File metadata and controls
88 lines (73 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.PowerShell.ConsoleGuiTools;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Management.Automation;
using Microsoft.PowerShell.ConsoleGuiTools.Models;
/// <summary>
/// Helper class for formatting objects passed pipeline object into text.
/// </summary>
internal static class FormatHelper
{
/// <summary>
/// Formats the output of a command as a table with the selected properties of the object in each column.
/// The object type determines the default layout and properties that are displayed in each column.
/// You can use the Property parameter to select the properties that you want to display.
/// </summary>
/// <param name="inputs">Collection of <see cref="PSObject"/></param>
/// <param name="properties">Specifies the object properties that appear in the display and the order in which they appear.
/// Type one or more property names, separated by commas, or use a hash table to display a calculated property.
/// Wildcards are permitted.</param>
/// <returns><see cref="Table"/> data transfer object that contains header and rows in string.</returns>
/// <remarks>
/// <c>Format-Table</c> Powershell command is used to format the inputs objects as a table.
/// </remarks>
internal static Table FormatTable(IReadOnlyList<PSObject> inputs, bool force, object[] properties = null)
{
if (inputs.Count == 0)
{
return Table.Empty;
}
using var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);
ps.AddCommand("Format-Table");
ps.AddParameter("AutoSize");
if (properties != null)
{
ps.AddParameter("Property", properties);
}
if (force == true)
{
ps.AddParameter("Force");
}
ps.AddParameter("InputObject", inputs);
// Format-Table's output objects are internal to Powershell,
// we cannot use them here, so we need to convert it to a string as workaround.
ps.AddCommand("Out-String");
var results = ps.Invoke();
var text = results.FirstOrDefault()?.BaseObject.ToString();
var lines = text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)
.Where(line => string.IsNullOrEmpty(line) == false).ToList();
/*
* Format-Table sometimes outputs a label on the top based on input's data type.
* We need to detect and skip the label and extract only header and rows.
* Strategy is to detect the index of the line under the header with dashes and spaces ('---- -- --- ').
*/
static bool isHeaderLine(string text) => text.Contains('-') && text.All(c => c == '-' || c == ' ');
var headerLineIndex = lines.FindIndex(isHeaderLine);
if (headerLineIndex == -1)
{
// unexpected result, return the whole text
headerLineIndex = 1;
}
return new Table
{
Header = lines.Skip(headerLineIndex - 1).FirstOrDefault(),
HeaderLine = lines.Skip(headerLineIndex).FirstOrDefault(),
Rows = lines.Skip(headerLineIndex + 1)
};
}
}