in src/common/IO/Output/ConsoleOutput.cs [162:255]
private void WriteTable<T>(IEnumerable<T> outputDataItems)
{
if (outputDataItems is null)
{
throw new ArgumentNullException(nameof(outputDataItems));
}
// Retrieve public properties of the data, and make sure that they are not to be ignored in Table format.
var properties = typeof(T).GetProperties().Where(p => !Attribute.IsDefined(p, typeof(TableOutputFormatIgnore)));
// Get the formatted data items
var formattedDataItems = new List<List<string>>();
bool hasSelectedElement = false;
foreach (var item in outputDataItems)
{
var formattedDataItem = properties.Select(p =>
{
var value = p.GetValue(item);
// Special case the "Selected" field
if (StringComparer.OrdinalIgnoreCase.Equals(p.Name, "Selected") && p.PropertyType == typeof(bool))
{
bool isSelected = (bool)value;
if (isSelected)
{
hasSelectedElement = true;
return ActiveRowHeader;
}
return InactiveRowHeader;
}
// Special case Date fields
if (p.PropertyType == typeof(DateTime))
{
return ((DateTime)value).FormatDateTimeUtcAsAgoString(roundToLargestUnitOfTime: true);
}
return value?.ToString() ?? string.Empty;
}).ToList();
formattedDataItems.Add(formattedDataItem);
}
// Get the table headers
var headers = properties.Select(p =>
{
if (!StringComparer.OrdinalIgnoreCase.Equals(p.Name, "Selected"))
{
var displayName = p.GetCustomAttributes(typeof(DisplayNameAttribute), false).SingleOrDefault();
if (displayName != null)
{
return ((DisplayNameAttribute)displayName).DisplayName;
}
else
{
return p.Name;
}
}
else
{
// Special case for the "Selected" column
return hasSelectedElement ? InactiveRowHeader : ActiveRowHeader;
}
});
// Calculate column widths
var columnWidths = new List<int>();
foreach (var header in headers)
{
columnWidths.Add(header.Length);
}
formattedDataItems.ExecuteForEach(formattedDataItem =>
{
for (var i = 0; i < formattedDataItem.Count; i++)
{
columnWidths[i] = Math.Max(columnWidths[i], formattedDataItem[i]?.Length ?? 0);
}
});
var formattedRowsToLog = new List<string>();
formattedRowsToLog.Add(this.WriteTableRow(headers.ToList(), columnWidths));
var headerUnderlines = columnWidths.Select(width => new string('-', width)).ToList();
formattedRowsToLog.Add(this.WriteTableRow(headerUnderlines, columnWidths));
foreach (var formattedDataItem in formattedDataItems)
{
formattedRowsToLog.Add(this.WriteTableRow(formattedDataItem, columnWidths));
}
var formattedOutputToLog = string.Join(Environment.NewLine, formattedRowsToLog);
_log.WithoutTelemetry.Info($"Console output (Table):{Environment.NewLine}{formattedOutputToLog}");
}