8000 Makes Format-Custom treat DateTime as a scalar unless Expaned by powercode · Pull Request #18293 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Makes Format-Custom treat DateTime as a scalar unless Expaned #18293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
8000
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,31 @@ public FormatCustomCommand()
/// will be determined using property sets, etc.
/// </summary>
[Parameter(Position = 0)]
public object[] Property
{
get { return _props; }

set { _props = value; }
}

private object[] _props;
public object[] Property { get; set; }

/// <summary>
/// Specifies the number of levels to recurse complex properties
/// </summary>
/// <value></value>
[ValidateRangeAttribute(1, int.MaxValue)]
[Parameter]
public int Depth
{
get { return _depth; }

set { _depth = value; }
}
public int Depth { get; set; } = ComplexSpecificParameters.maxDepthAllowable;

private int _depth = ComplexSpecificParameters.maxDepthAllowable;
/// <inheritdoc cref="ComplexSpecificParameters.ScalarTypesToExpand" />
[Parameter]
[ValidateSet("System.DateTime", "System.DateTimeOffset")] // if we get more types here, consider moving to IValidateSetValuesGenerator
public string[] ExpandType { get; set; }

#endregion

internal override FormattingCommandLineParameters GetCommandLineParameters()
{
FormattingCommandLineParameters parameters = new();

if (_props != null)
if (Property != null)
{
ParameterProcessor processor = new(new FormatObjectParameterDefinition());
TerminatingErrorContext invocationContext = new(this);
parameters.mshParameterList = processor.ProcessParameters(_props, invocationContext);
parameters.mshParameterList = processor.ProcessParameters(Property, invocationContext);
}

if (!string.IsNullOrEmpty(this.View))
Expand All @@ -88,7 +79,8 @@ internal override FormattingCommandLineParameters GetCommandLineParameters()
parameters.expansion = ProcessExpandParameter();

ComplexSpecificParameters csp = new();
csp.maxDepth = _depth;
csp.maxDepth = Depth;
csp.ScalarTypesToExpand = ExpandType;
parameters.shapeParameters = csp;

return parameters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ internal enum ClassInfoDisplay { none, fullName, shortName }
/// Max depth of recursion on sub objects.
/// </summary>
internal int maxDepth = maxDepthAllowable;

/// <summary>
/// Gets or sets an array of type names that are by default rendered as scalar, but should be expanded.
/// </summary>
internal string[] ScalarTypesToExpand
{
get => _scalarTypesToExpand ?? Array.Empty<string>();
set => _scalarTypesToExpand = value;
}

private string[] _scalarTypesToExpand;
}

< 8000 /td>
#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,12 @@ internal TraversalInfo NextLevel
/// </summary>
internal sealed class ComplexViewObjectBrowser
{
private static readonly HashSet<string> s_defaultLeafTypes = new(System.StringComparer.OrdinalIgnoreCase)
{
"System.DateTime",
"System.DateTimeOffset"
};

internal ComplexViewObjectBrowser(FormatErrorManager resultErrorManager, PSPropertyExpressionFactory mshExpressionFactory, int enumerationLimit)
{
_errorManager = resultErrorManager;
Expand Down Expand Up @@ -445,7 +451,7 @@ internal ComplexViewEntry GenerateView(PSObject so, FormattingCommandLineParamet
// create a top level entry as root of the tree
ComplexViewEntry cve = new ComplexViewEntry();
var typeNames = so.InternalTypeNames;
if (TreatAsScalarType(typeNames))
if (TreatAsScalarType(typeNames, _complexSpecificParameters.ScalarTypesToExpand))
{
FormatEntry fe = new FormatEntry();

Expand Down Expand Up @@ -589,7 +595,7 @@ private void ProcessActiveAssociationList(PSObject so,
formatValueList.Add(new FormatNewLine());
DisplayEnumeration(e, level.NextLevel, AddIndentationLevel(formatValueList));
}
else if (val == null || TreatAsLeafNode(val, level))
else if (val == null || TreatAsLeafNode(val, level, _complexSpecificParameters.ScalarTypesToExpand))
{
DisplayLeaf(val, formatValueList);
}
Expand Down Expand Up @@ -640,7 +646,7 @@ private void DisplayEnumerationInner(IEnumerable e, TraversalInfo level, List<Fo
enumCount++;
}

if (TreatAsLeafNode(x, level))
if (TreatAsLeafNode(x, level, _complexSpecificParameters.ScalarTypesToExpand))
{
DisplayLeaf(x, formatValueList);
}
Expand Down Expand Up @@ -681,23 +687,46 @@ private void DisplayLeaf(object val, List<FormatValue> formatValueList)
/// </summary>
/// <param name="val">Object to verify.</param>
/// <param name="level">Current level of recursion.</param>
/// <returns></returns>
private static bool TreatAsLeafNode(object val, TraversalInfo level)
/// <param name="scalarTypesToExpand">Array of names of types that should not be rendered as scalars.</param>
/// <returns>True if it has to be treated as leaf node.</returns>
private static bool TreatAsLeafNode(object val, TraversalInfo level, string[] scalarTypesToExpand)
{
if (level.Level >= level.MaxDepth || val == null)
{
return true;
}

return TreatAsScalarType(PSObject.GetTypeNames(val));
return TreatAsScalarType(PSObject.GetTypeNames(val), scalarTypesToExpand);
}

/// <summary>
/// Treat as scalar check.
/// </summary>
/// <param name="typeNames">Name of the type to check.</param>
/// <param name="scalarTypesToExpand">Array of names of types that should not be rendered as scalars.</param>
/// <returns>True if it has to be treated as a scalar.</returns>
private static bool TreatAsScalarType(Collection<string> typeNames)
private static bool TreatAsScalarType(Collection<string> typeNames, string[] scalarTypesToExpand)
{
return DefaultScalarTypes.IsTypeInList(typeNames) || TypeIsScalarForComplexView(typeNames, scalarTypesToExpand);
}

private static bool TypeIsScalarForComplexView(Collection<string> typeNames, string[] scalarTypesToExpand)
{
return DefaultScalarTypes.IsTypeInList(typeNames);
foreach (var type in typeNames)
{
// if the type is in the scalarTypesToExpand, we should not treat it as a scalar
if (s_defaultLeafTypes.Contains(type))
{
if (System.Array.Find(scalarTypesToExpand, t => t == type) is not null)
{
return false;
}

return true;
}
}

return false;
}

private string GetObjectDisplayName(PSObject so)
Expand Down
47B1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,63 @@ Describe "Format-Custom" -Tags "CI" {
}

}

Context "Treats datetime as scalar unless Expanded" {
BeforeAll{
$date = [DateTime]::new(2000,01,02)
$obj = [PSCustomObject] @{
Date = $date
PSTypeName="DateTimeTest"
}
# locale aware formatting
$dateStr = $date.ToString()
$shortDate = $date.Date.ToString()
$longDate = $date.ToString("F")

}

It "Should treat datetime as scalar by default" {
$res = ($obj | Format-Custom | Out-String).Trim()
$res | Should -BeExactly @"
class DateTimeTest
{
Date = $dateStr
}
"@
}

It "Treats datetime as non-scalar when Expanded" {

$expected = @"
class DateTimeTest
{
Date =
class DateTime
{
Date = $shortDate
Day = 2
DayOfWeek = Sunday
DayOfYear = 2
Hour = 0
Kind = Unspecified
Millisecond = 0
Microsecond = 0
Nanosecond = 0
Minute = 0
Month = 1
Second = 0
Ticks = 630823680000000000
TimeOfDay = 00:00:00
Year = 2000
DateTime = $longDate
}
}
"@ -replace 'Date =\r?\n', "Date = `n" -replace '\r\n', "`n" # the 'Date = ' replacement is needed as editors trim whitespace at the end of lines.

$actual = ($obj | Format-Custom -ExpandType:System.DateTime -Depth:1 | Out-String).Trim() -replace '\r?\n', "`n"
$actual | Should -BeExactly $expected
}
}
}

Describe "Format-Custom DRT basic functionality" -Tags "CI" {
Expand Down
0