Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
277 changes: 269 additions & 8 deletions TruePath.SystemIo/PathIo.cs

Large diffs are not rendered by default.

23 changes: 8 additions & 15 deletions TruePath.SystemIo/PublicAPI/net8.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,17 @@ static TruePath.SystemIo.PathIo.CreateDirectory(this TruePath.AbsolutePath path,
static TruePath.SystemIo.PathIo.CreateSymbolicLink(this TruePath.AbsolutePath path, TruePath.AbsolutePath pathToTarget) -> System.IO.FileSystemInfo!
static TruePath.SystemIo.PathIo.Decrypt(this TruePath.AbsolutePath path) -> void
static TruePath.SystemIo.PathIo.Encrypt(this TruePath.AbsolutePath path) -> void
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.EnumerationOptions! enumerationOptions) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.EnumerationOptions! enumerationOptions) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.GetDirectoryRoot(this TruePath.AbsolutePath path) -> string!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path) -> string![]!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> string![]!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.EnumerationOptions! enumerationOptions) -> string![]!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> string![]!
static TruePath.SystemIo.PathIo.GetParent(this TruePath.AbsolutePath path) -> System.IO.DirectoryInfo?
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.EnumerationOptions! enumerationOptions) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.EnumerationOptions! enumerationOptions) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.Open(this TruePath.AbsolutePath path, System.IO.FileStreamOptions! options) -> System.IO.FileStream!
static TruePath.SystemIo.PathIo.OpenHandle(this TruePath.AbsolutePath path, System.IO.FileMode mode = System.IO.FileMode.Open, System.IO.FileAccess access = System.IO.FileAccess.Read, System.IO.FileShare share = System.IO.FileShare.Read, System.IO.FileOptions options = System.IO.FileOptions.None, long preallocationSize = 0) -> Microsoft.Win32.SafeHandles.SafeFileHandle!
static TruePath.SystemIo.PathIo.Replace(this TruePath.AbsolutePath sourceFile, TruePath.AbsolutePath destinationFile, TruePath.AbsolutePath destinationBackupFile) -> void
static TruePath.SystemIo.PathIo.Replace(this TruePath.AbsolutePath sourceFile, TruePath.AbsolutePath destinationFile, TruePath.AbsolutePath destinationBackupFile, bool ignoreMetadataErrors) -> void
static TruePath.SystemIo.PathIo.ResolveLinkTarget(this TruePath.AbsolutePath linkPath, bool returnFinalTarget) -> System.IO.FileSystemInfo?
static TruePath.SystemIo.PathIo.SetCurrentDirectory(this TruePath.AbsolutePath path) -> void
static TruePath.SystemIo.PathIo.SetUnixFileMode(this TruePath.AbsolutePath path, System.IO.UnixFileMode mode) -> void
18 changes: 6 additions & 12 deletions TruePath.SystemIo/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
#nullable enable
static TruePath.SystemIo.PathIo.Decrypt(this TruePath.AbsolutePath path) -> void
static TruePath.SystemIo.PathIo.Encrypt(this TruePath.AbsolutePath path) -> void
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<string!>!
static TruePath.SystemIo.PathIo.GetDirectoryRoot(this TruePath.AbsolutePath path) -> string!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path) -> string![]!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> string![]!
static TruePath.SystemIo.PathIo.GetFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> string![]!
static TruePath.SystemIo.PathIo.GetParent(this TruePath.AbsolutePath path) -> System.IO.DirectoryInfo?
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateDirectories(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.EnumerateFileSystemEntries(this TruePath.AbsolutePath path, string! searchPattern, System.IO.SearchOption searchOption) -> System.Collections.Generic.IEnumerable<TruePath.AbsolutePath>!
static TruePath.SystemIo.PathIo.Replace(this TruePath.AbsolutePath sourceFile, TruePath.AbsolutePath destinationFile, TruePath.AbsolutePath destinationBackupFile) -> void
static TruePath.SystemIo.PathIo.Replace(this TruePath.AbsolutePath sourceFile, TruePath.AbsolutePath destinationFile, TruePath.AbsolutePath destinationBackupFile, bool ignoreMetadataErrors) -> void
static TruePath.SystemIo.PathIo.SetCurrentDirectory(this TruePath.AbsolutePath path) -> void
18 changes: 17 additions & 1 deletion TruePath.SystemIo/path-io-exclusions.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2026 TruePath contributors <https://github.com/ForNeVeR/TruePath>
#
# SPDX-License-Identifier: MIT
#
# BCL methods that must not be exposed as PathIo extension methods.
#
# One XML documentation ID per line, e.g.:
Expand All @@ -10,4 +14,16 @@
# argument (e.g. DeleteEmptyDirectory/DeleteDirectoryRecursively forwarding to
# Directory.Delete(string, bool)).
#
# (No entries yet.)

# Covered by the EnumerateFileSystemEntries extensions.
M:System.IO.Directory.GetFileSystemEntries(System.String)
M:System.IO.Directory.GetFileSystemEntries(System.String,System.String)
M:System.IO.Directory.GetFileSystemEntries(System.String,System.String,System.IO.EnumerationOptions)
M:System.IO.Directory.GetFileSystemEntries(System.String,System.String,System.IO.SearchOption)

# Covered by the AbsolutePath.Parent and AbsolutePath.PathRoot properties.
M:System.IO.Directory.GetParent(System.String)
M:System.IO.Directory.GetDirectoryRoot(System.String)

# Covered by the AbsolutePath.CurrentWorkingDirectory property.
M:System.IO.Directory.SetCurrentDirectory(System.String)
3 changes: 0 additions & 3 deletions TruePath.SystemIo/path-io-exclusions.txt.license

This file was deleted.

16 changes: 8 additions & 8 deletions TruePath.Tests/PathIoCompletenessTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ private static string PathIoParameterType(ParameterInfo parameter)

private static HashSet<string> LoadExclusions()
{
return File.ReadAllLines(Path.Combine(RepositoryRoot(), "TruePath.SystemIo", "path-io-exclusions.txt"))
return (RepositoryRoot() / "TruePath.SystemIo" / "path-io-exclusions.txt").ReadAllLines()
.Select(line => line.Trim())
.Where(line => line.Length > 0 && !line.StartsWith("#", StringComparison.Ordinal))
.ToHashSet();
Expand All @@ -95,7 +95,7 @@ private static HashSet<string> LoadExclusions()
/// </summary>
private static HashSet<(string TypeName, string MethodName, int ArgumentCount)> LoadForwardedCalls()
{
var source = File.ReadAllText(Path.Combine(RepositoryRoot(), "TruePath.SystemIo", "PathIo.cs"));
var source = (RepositoryRoot() / "TruePath.SystemIo" / "PathIo.cs").ReadAllText();
var calls = new HashSet<(string, string, int)>();
foreach (Match match in Regex.Matches(source, @"\b(?<type>File|Directory)\.(?<method>\w+)\((?<args>[^()]*)\)"))
{
Expand All @@ -108,14 +108,14 @@ private static HashSet<string> LoadExclusions()
return calls;
}

private static string RepositoryRoot()
private static AbsolutePath RepositoryRoot()
{
var directory = new DirectoryInfo(AppContext.BaseDirectory);
while (directory != null && !File.Exists(Path.Combine(directory.FullName, "TruePath.sln")))
directory = directory.Parent;
AbsolutePath? directory = new AbsolutePath(AppContext.BaseDirectory);
while (directory != null && !(directory.Value / "TruePath.slnx").ExistsFile())
directory = directory.Value.Parent;

if (directory == null) Assert.Skip("Repository root with TruePath.sln not found.");
return directory.FullName;
if (directory == null) Assert.Fail("Repository root with TruePath.slnx not found.");
return directory.Value;
}

private static string DocId(MethodInfo method)
Expand Down
40 changes: 40 additions & 0 deletions TruePath.Tests/PathIoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,46 @@ public void GetFilesByLocalPathPatternTest()
});
}

[Fact]
public void EnumerateDirectoriesTest()
{
DoWithTempFolder(tempFolder =>
{
var alpha = tempFolder / "alpha";
var beta = tempFolder / "beta";
var nested = alpha / "nested";
nested.CreateDirectory();
beta.CreateDirectory();
(tempFolder / "file.txt").WriteAllText("test");

Assert.Equal([alpha, beta], tempFolder.EnumerateDirectories().OrderBy(x => x.Value));
Assert.Equal([alpha], tempFolder.EnumerateDirectories("a*"));
Assert.Equal(
[alpha, nested, beta],
tempFolder.EnumerateDirectories("*", SearchOption.AllDirectories).OrderBy(x => x.Value));
});
}

[Fact]
public void EnumerateFileSystemEntriesTest()
{
DoWithTempFolder(tempFolder =>
{
var alpha = tempFolder / "alpha";
var nested = alpha / "nested.txt";
var beta = tempFolder / "beta.txt";
alpha.CreateDirectory();
nested.WriteAllText("test");
beta.WriteAllText("test");

Assert.Equal([alpha, beta], tempFolder.EnumerateFileSystemEntries().OrderBy(x => x.Value));
Assert.Equal([alpha], tempFolder.EnumerateFileSystemEntries("a*"));
Assert.Equal(
[alpha, nested, beta],
tempFolder.EnumerateFileSystemEntries("*", SearchOption.AllDirectories).OrderBy(x => x.Value));
});
}

private static void DoWithTempFolder(Action<AbsolutePath> test)
{
var tempFolder = Temporary.CreateTempFolder();
Expand Down
Loading
Loading