Skip to content

Commit b11df98

Browse files
authored
Merge pull request #33 from santisq/9-sort-by-ascending-values
9 sort by ascending values
2 parents e451b59 + 1386fd3 commit b11df98

12 files changed

+180
-71
lines changed

CHANGELOG.md

Lines changed: 93 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,69 @@
11
# CHANGELOG
22

3+
- __08/29/2024__
4+
- Added method `.GetUnderlyingObject()`. Outputs the underlying `FileSystemInfo` instance.
5+
- Fixes [__Issue #9: Sort by ascending values__][1]:
6+
- PSTree v2.1.16
7+
8+
```powershell
9+
PS ..\PSTree> pstree -Directory -Depth 2
10+
11+
Source: D:\...\PSTree
12+
13+
Mode Length Hierarchy
14+
---- ------ ---------
15+
d---- 25.27 KB PSTree
16+
d---- 3.72 KB ├── tools
17+
d---- 16.96 KB │ ├── ProjectBuilder
18+
d---- 0.00 B │ └── Modules
19+
d---- 13.66 KB ├── tests
20+
d---- 0.00 B ├── src
21+
d---- 13.26 KB │ └── PSTree
22+
d---- 168.69 KB ├── output
23+
d---- 92.50 KB │ ├── TestResults
24+
d---- 0.00 B │ └── PSTree
25+
d---- 6.26 KB ├── module
26+
d---- 0.00 B ├── docs
27+
d---- 7.37 KB │ └── en-US
28+
d---- 4.11 KB ├── .vscode
29+
d---- 0.00 B └── .github
30+
d---- 4.10 KB └── workflows
31+
```
32+
33+
- PSTree v2.1.17
34+
35+
```powershell
36+
PS ..\PSTree> pstree -Directory -Depth 2
37+
38+
Source: D:\Zen\Documents\Scripts\PSTree
39+
40+
Mode Length Hierarchy
41+
---- ------ ---------
42+
d---- 25.27 KB PSTree
43+
d---- 0.00 B ├── .github
44+
d---- 4.10 KB │ └── workflows
45+
d---- 4.11 KB ├── .vscode
46+
d---- 0.00 B ├── docs
47+
d---- 7.37 KB │ └── en-US
48+
d---- 6.26 KB ├── module
49+
d---- 168.69 KB ├── output
50+
d---- 0.00 B │ ├── PSTree
51+
d---- 92.50 KB │ └── TestResults
52+
d---- 0.00 B ├── src
53+
d---- 13.26 KB │ └── PSTree
54+
d---- 13.66 KB ├── tests
55+
d---- 3.72 KB └── tools
56+
d---- 0.00 B ├── Modules
57+
d---- 16.96 KB └── ProjectBuilder
58+
```
59+
360
- __02/26/2024__
461
- Added method `.GetFormattedLength()`. Outputs the friendly `.Length` representation of `PSTreeFile` and `PSTreeDirectory` instances.
562
6-
```powershell
7-
PS ..\PSTree> (Get-PSTree D:\ -RecursiveSize -Depth 0).GetFormattedLength()
8-
629.59 GB
9-
```
63+
```powershell
64+
PS ..\PSTree> (Get-PSTree D:\ -RecursiveSize -Depth 0).GetFormattedLength()
65+
629.59 GB
66+
```
1067
1168
- __10/05/2023__
1269
- Added Parameter `-Include`. Works very similar to `-Exclude`, the patterns are evaluated against the items `.FullName` property, however this parameter targets only files (`FileInfo` instances).
@@ -19,20 +76,20 @@
1976
- [x] <https://github.com/santisq/PSTree/issues/20> `-Depth` parameter type was changed from `int` to `uint` and the documentation was updated accordingly.
2077
2178
- __07/28/2023__
22-
- Added `.ToString()` method to `PSTreeFileSystemInfo<T>` instances, the method resolves to the instances `.FullName` property similar to [`FileSystemInfo.ToString` Method](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesysteminfo.tostring?view=net-7.0#system-io-filesysteminfo-tostring). Now it should be possible to pipe `Get-PSTree` output to `Get-Item` and `Get-ChildItem` when needed:
79+
- Added `.ToString()` method to `PSTreeFileSystemInfo<T>` instances, the method resolves to the instances `.FullName` property similar to [`FileSystemInfo.ToString` Method][14]. Now it should be possible to pipe `Get-PSTree` output to `Get-Item` and `Get-ChildItem` when needed:
2380
2481
```powershell
2582
Get-PStree -Depth 0 | Get-Item
2683
```
2784
28-
- Added `.Refresh()` method to `PSTreeFileSystemInfo<T>`, functionality is the same as [`FileSystemInfo.Refresh` Method](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesysteminfo.refresh?view=net-7.0#system-io-filesysteminfo-refresh).
85+
- Added `.Refresh()` method to `PSTreeFileSystemInfo<T>`, functionality is the same as [`FileSystemInfo.Refresh` Method][15].
2986
- Reorganizing source files and Pester tests.
3087
- Added more Pester tests.
3188
- Fixed a few documentation typos.
3289
3390
- __07/03/2023__
3491
- Added `-Path` parameter, now both `-Path` and `-LiteralPath` parameters take `string[]` as input and support pipeline input.
35-
- Added Pester tests, Code Coverage and coverage upload to [codecov.io](https://app.codecov.io/gh/santisq/PSTree).
92+
- Added Pester tests, Code Coverage and coverage upload to [codecov.io][16].
3693
- Removed `.Size` Property from `PSTreeFile` and `PSTreeDirectory` instances. The `Size` column has been renamed to `Length` and moved to the left-hand side of the `Hierarchy` column (I know it looks much better on the right-hand side :expressionless: but having it in the left allows for fixed width in the first 2 columns, which in turn brings less formatting issues :man_shrugging:...).
3794
3895
The default display for this column is available through `[PSTree.Internal._Format]::GetFormattedLength(...)`, for example:
@@ -76,15 +133,15 @@
76133
```
77134
78135
- __03/22/2023__
79-
- `Get-PSTree` is now a binary cmdlet. Functionality remains the same. Big thanks to [SeeminglyScience](https://github.com/SeeminglyScience/) and [jborean93](https://github.com/jborean93/) for all their help!
80-
- Added `-Exclude` parameter to the cmdlet. The parameter accepts wildcards and patterns are matched with the object's `.FullName` property. For more details checkout [cmdlet docs](/docs/en-US/Get-PSTree.md).
136+
- `Get-PSTree` is now a binary cmdlet. Functionality remains the same. Big thanks to [SeeminglyScience][17] and [jborean93][18] for all their help!
137+
- Added `-Exclude` parameter to the cmdlet. The parameter accepts wildcards and patterns are matched with the object's `.FullName` property. For more details checkout [cmdlet docs][19].
81138
82139
- __02/25/2023__
83140
- Fixed a bug that made `Get-PSTree` use `-Recurse` by default.
84141
- Added [ETS properties](./PSTree/PSTree.Types.ps1xml) to `PSTreeDirectory` and `PSTreeFile` instances that would make exporting the output easier.
85142
86143
- __10/23/2022__
87-
- __PSTree Module__ is now published to the [PowerShell Gallery](https://www.powershellgallery.com/)!
144+
- __PSTree Module__ is now published to the [PowerShell Gallery][20]!
88145
- Introducing `-RecursiveSize` switch parameter to `Get-PSTree`. By default, `Get-PSTree` only displays the size of folders __based on the sum of the files length in each Directory__.
89146
This parameter allows to calculate the recursive size of folders in the hierarchy, similar to how explorer does it. __It's important to note that this is a more expensive operation__, in order to calculate the recursive size, all folders in the hierarchy need to be traversed.
90147
@@ -111,8 +168,8 @@ d---- └── Format 1.83 Kb
111168
```
112169

113170
- __06/19/2022__
114-
- Added [format view](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_format.ps1xml?view=powershell-7.2&viewFallbackFrom=powershell-6) for the Module - [`PSTree.Format.ps1xml`](PSTree/PSTree.Format.ps1xml).
115-
- The module now uses [`EnumerateFileSystemInfos()`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.enumeratefilesysteminfos?view=net-6.0#system-io-directoryinfo-enumeratefilesysteminfos) instance method.
171+
- Added [format view][12] for the Module - [`PSTree.Format.ps1xml`][13].
172+
- The module now uses [`EnumerateFileSystemInfos()`][11] instance method.
116173
- Improved error handling (a lot).
117174
- `-Files` parameter has been replaced with `-Directory` parameter, now the module displays files by default.
118175
- `-Deep` parameter has been replaced with `-Recurse` parameter, same functionality.
@@ -140,18 +197,39 @@ d---- └── Format 1.83 Kb
140197

141198
- __05/24/2022__
142199

143-
- Lots of code improvements have been done to the Module and improved error handling. Now uses the [`GetDirectories()`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getdirectories?view=net-6.0#system-io-directoryinfo-getdirectories) and [`GetFiles()`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getfiles?view=net-6.0#system-io-directoryinfo-getfiles) methods from [`System.IO.DirectoryInfo`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo?view=net-6.0). Each `PSTreeDirectory` instance now holds an instance of `DirectoryInfo`. [`System.Collections.Stack`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.stack?view=net-6.0) has been changed for [`System.Collections.Generic.Stack<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.stack-1?view=net-6.0).
200+
- Lots of code improvements have been done to the Module and improved error handling. Now uses the [`GetDirectories()`][10] and [`GetFiles()`][9] methods from [`System.IO.DirectoryInfo`][8]. Each `PSTreeDirectory` instance now holds an instance of `DirectoryInfo`. [`System.Collections.Stack`][5] has been changed for [`System.Collections.Generic.Stack<T>`][7].
144201

145202
- __04/21/2022__
146203

147-
- __PSTree Module__ now uses [`System.Collections.Stack`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.stack?view=net-6.0) instead of recursion, performance should be much better now and functionality remains the same. Special thanks to [IISResetMe](https://github.com/IISResetMe).
204+
- __PSTree Module__ now uses [`System.Collections.Stack`][5] instead of recursion, performance should be much better now and functionality remains the same. Special thanks to [IISResetMe][6].
148205

149206
- __01/02/2022__
150207

151208
- __PSTree Module__ now has it's own classes, functionality remains the same however a lot has been improved.
152-
- Recursion is now done using the static methods [`[System.IO.Directory]::GetDirectories()`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getdirectories?view=net-6.0) and [`[System.IO.Directory]::GetFiles()`](https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles?view=net-6.0) instead of [`Get-ChildItem`](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem).
209+
- Recursion is now done using the static methods [`[System.IO.Directory]::GetDirectories()`][2] and [`[System.IO.Directory]::GetFiles()`][3] instead of [`Get-ChildItem`][4].
153210

154211
- __12/25/2021__
155212

156213
- `-Files` switch has been added to the Module, now you can display files in the hierarchy tree if desired.
157214
- `Type` property has been added to the output object and is now part of the _Default MemberSet_.
215+
216+
[1]: https://github.com/santisq/PSTree/issues/9
217+
[2]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getdirectories?view=net-6.0
218+
[3]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directory.getfiles?view=net-6.0
219+
[4]: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem
220+
[5]: https://docs.microsoft.com/en-us/dotnet/api/system.collections.stack?view=net-6.0
221+
[6]: https://github.com/IISResetMe
222+
[7]: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.stack-1?view=net-6.0
223+
[8]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo?view=net-6.0
224+
[9]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getfiles?view=net-6.0#system-io-directoryinfo-getfiles
225+
[10]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getdirectories?view=net-6.0#system-io-directoryinfo-getdirectories
226+
[11]: https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.enumeratefilesysteminfos?view=net-6.0#system-io-directoryinfo-enumeratefilesysteminfos
227+
[12]: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_format.ps1xml?view=powershell-7.2&viewFallbackFrom=powershell-6
228+
[13]: PSTree/PSTree.Format.ps1xml
229+
[14]: https://learn.microsoft.com/en-us/dotnet/api/system.io.filesysteminfo.tostring?view=net-7.0#system-io-filesysteminfo-tostring
230+
[15]: https://learn.microsoft.com/en-us/dotnet/api/system.io.filesysteminfo.refresh?view=net-7.0#system-io-filesysteminfo-refresh
231+
[16]: https://app.codecov.io/gh/santisq/PSTree
232+
[17]: https://github.com/SeeminglyScience/
233+
[18]: https://github.com/jborean93/
234+
[19]: /docs/en-US/Get-PSTree.md
235+
[20]: https://www.powershellgallery.com/

module/PSTree.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
RootModule = 'bin/netstandard2.0/PSTree.dll'
1212

1313
# Version number of this module.
14-
ModuleVersion = '2.1.16'
14+
ModuleVersion = '2.1.17'
1515

1616
# Supported PSEditions
1717
# CompatiblePSEditions = @()

src/PSTree/Commands/GetPSTreeCommand.cs

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ namespace PSTree;
99
[Cmdlet(VerbsCommon.Get, "PSTree", DefaultParameterSetName = "Path")]
1010
[OutputType(typeof(PSTreeDirectory), typeof(PSTreeFile))]
1111
[Alias("pstree")]
12-
public sealed class GetPSTreeCommand : PSCmdlet
12+
public sealed partial class GetPSTreeCommand : PSCmdlet
1313
{
1414
private bool _isLiteral;
1515

16-
private bool _withExclude;
17-
18-
private bool _withInclude;
19-
2016
private string[]? _paths;
2117

2218
private WildcardPattern[]? _excludePatterns;
@@ -29,6 +25,8 @@ public sealed class GetPSTreeCommand : PSCmdlet
2925

3026
private readonly PSTreeCache _cache = new();
3127

28+
private readonly PSTreeComparer _comparer = new();
29+
3230
[Parameter(
3331
ParameterSetName = "Path",
3432
Position = 0,
@@ -104,25 +102,20 @@ protected override void BeginProcessing()
104102
_excludePatterns = Exclude
105103
.Select(e => new WildcardPattern(e, wpoptions))
106104
.ToArray();
107-
108-
_withExclude = true;
109105
}
110106

111-
// this Parameter only targets files, there is no reason to use it
112-
// if -Directory is in use
107+
// this Parameter only targets files, there is no reason to use it if -Directory is in use
113108
if (Include is not null && !Directory.IsPresent)
114109
{
115110
_includePatterns = Include
116111
.Select(e => new WildcardPattern(e, wpoptions))
117112
.ToArray();
118-
119-
_withInclude = true;
120113
}
121114
}
122115

123116
protected override void ProcessRecord()
124117
{
125-
_paths ??= new[] { SessionState.Path.CurrentLocation.Path };
118+
_paths ??= [SessionState.Path.CurrentLocation.Path];
126119

127120
foreach (string path in _paths.NormalizePath(_isLiteral, this))
128121
{
@@ -148,37 +141,16 @@ private PSTreeFileSystemInfo[] Traverse(
148141
_cache.Clear();
149142
_stack.Push(new PSTreeDirectory(directory, source));
150143

151-
bool ShouldInclude(FileInfo file)
152-
{
153-
if (!_withInclude)
154-
{
155-
return true;
156-
}
157-
158-
return _includePatterns.Any(e => e.IsMatch(file.FullName));
159-
}
160-
161-
bool ShouldExclude(FileSystemInfo item)
162-
{
163-
if (!_withExclude)
164-
{
165-
return false;
166-
}
167-
168-
return _excludePatterns.Any(e => e.IsMatch(item.FullName));
169-
}
170-
171-
172144
while (_stack.Count > 0)
173145
{
174-
IEnumerable<FileSystemInfo> enumerator;
146+
IOrderedEnumerable<FileSystemInfo> enumerator;
175147
PSTreeDirectory next = _stack.Pop();
176148
int level = next.Depth + 1;
177149
long size = 0;
178150

179151
try
180152
{
181-
enumerator = next.EnumerateFileSystemInfos();
153+
enumerator = next.GetSortedEnumerable(_comparer);
182154
bool keepProcessing = level <= Depth;
183155

184156
foreach (FileSystemInfo item in enumerator)
@@ -188,7 +160,7 @@ bool ShouldExclude(FileSystemInfo item)
188160
continue;
189161
}
190162

191-
if (ShouldExclude(item))
163+
if (ShouldExclude(item, _excludePatterns))
192164
{
193165
continue;
194166
}
@@ -202,7 +174,7 @@ bool ShouldExclude(FileSystemInfo item)
202174
continue;
203175
}
204176

205-
if (keepProcessing && ShouldInclude(file))
177+
if (keepProcessing && ShouldInclude(file, _includePatterns))
206178
{
207179
_cache.AddFile(file, level, source);
208180
}
@@ -247,4 +219,43 @@ bool ShouldExclude(FileSystemInfo item)
247219

248220
return _cache.GetTree();
249221
}
222+
223+
private static bool MatchAny(
224+
FileSystemInfo item,
225+
WildcardPattern[] patterns)
226+
{
227+
foreach (WildcardPattern pattern in patterns)
228+
{
229+
if (pattern.IsMatch(item.FullName))
230+
{
231+
return true;
232+
}
233+
}
234+
235+
return false;
236+
}
237+
238+
private static bool ShouldInclude(
239+
FileInfo file,
240+
WildcardPattern[]? patterns)
241+
{
242+
if (patterns is null)
243+
{
244+
return true;
245+
}
246+
247+
return MatchAny(file, patterns);
248+
}
249+
250+
private static bool ShouldExclude(
251+
FileSystemInfo item,
252+
WildcardPattern[]? patterns)
253+
{
254+
if (patterns is null)
255+
{
256+
return false;
257+
}
258+
259+
return MatchAny(item, patterns);
260+
}
250261
}

src/PSTree/Internal/_FormattingInternals.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace PSTree.Internal;
1111
public static class _FormattingInternals
1212
{
1313
private readonly static string[] s_suffix =
14-
{
14+
[
1515
"B",
1616
"KB",
1717
"MB",
@@ -21,7 +21,7 @@ public static class _FormattingInternals
2121
"EB",
2222
"ZB",
2323
"YB"
24-
};
24+
];
2525

2626
[Hidden, EditorBrowsable(EditorBrowsableState.Never)]
2727
public static string GetFormattedDate(DateTime date) =>

src/PSTree/PSTreeCache.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ internal sealed class PSTreeCache
1111

1212
internal PSTreeCache()
1313
{
14-
_items = new();
15-
_files = new();
14+
_items = [];
15+
_files = [];
1616
}
1717

1818
internal void AddFile(FileInfo file, int depth, string source) =>
@@ -25,7 +25,7 @@ internal void TryAddFiles()
2525
{
2626
if (_files.Count > 0)
2727
{
28-
_items.AddRange(_files.ToArray());
28+
_items.AddRange([.. _files]);
2929
_files.Clear();
3030
}
3131
}

src/PSTree/PSTreeComparer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
4+
namespace PSTree;
5+
6+
internal sealed class PSTreeComparer : IComparer<FileSystemInfo>
7+
{
8+
public int Compare(FileSystemInfo x, FileSystemInfo y) =>
9+
x is DirectoryInfo && y is DirectoryInfo
10+
? y.Name.CompareTo(x.Name) // Directories in descending order
11+
: x.Name.CompareTo(y.Name); // Files in ascending order
12+
}

0 commit comments

Comments
 (0)