NDepend.Path is framework to handle all sorts of paths operations: File, Directory, Absolute, Drive Letter, UNC, Relative, prefixed with an Environment Variable, that contain a Variable etc...
This framework is used in the product NDepend to handle all paths operations.
The project is hosted on Azure DevOps under the endjin-labs
org.
The NuGet packages for the project, hosted on NuGet.org are:
- Jan 30, 2014 - Initial Release from Patrick Smacchia, author of NDepend
- April 14 2015 - Werner Putschögl creates & publishes a nuget package
- June 23 2020 - endjin updates project to .NET Standard 2.1 and publishes new nuget package.
NDepend.Path is available under the MIT open source license.
This project has adopted a code of conduct adapted from the Contributor Covenant to clarify expected behavior in our community. This code of conduct has been adopted by many other projects. For more information see the Code of Conduct FAQ or contact hello@endjin.com with any additional questions or comments.
var absoluteFilePath = @"C:\Dir\File.txt".ToAbsoluteFilePath();
Assert.IsTrue(absoluteFilePath.FileName == "File.txt");
Assert.IsTrue(absoluteFilePath.Kind == AbsolutePathKind.DriveLetter);
Assert.IsTrue(absoluteFilePath.DriveLetter.Letter == 'C');
var absoluteUNCDirectoryPath = @"\\Server\Share\Dir".ToAbsoluteDirectoryPath();
Assert.IsTrue(absoluteUNCDirectoryPath.DirectoryName == "Dir");
Assert.IsTrue(absoluteUNCDirectoryPath.Kind == AbsolutePathKind.UNC);
Assert.IsTrue(absoluteUNCDirectoryPath.UNCServer == "Server");
Assert.IsTrue(absoluteUNCDirectoryPath.UNCShare == "Share");
Assert.IsTrue(absoluteFilePath.ParentDirectoryPath.ToString() == @"C:\Dir");
Assert.IsTrue(absoluteUNCDirectoryPath.GetChildFileWithName("File.txt").ToString() == @"\\Server\Share\Dir\File.txt");
Assert.IsTrue(absoluteUNCDirectoryPath.GetBrotherDirectoryWithName("Dir2").ToString() == @"\\Server\Share\Dir2");
if (absoluteUNCDirectoryPath.Exists) {
var filePaths = absoluteUNCDirectoryPath.ChildrenFilesPath;
var dirPaths = absoluteUNCDirectoryPath.ChildrenDirectoriesPath;
}
var absoluteDirectoryPath = @"C:\DirA\DirB".ToAbsoluteDirectoryPath();
var relativeFilePath = @"..\DirC\File.txt".ToRelativeFilePath();
var absoluteFilePath2 = relativeFilePath.GetAbsolutePathFrom(absoluteDirectoryPath);
Assert.IsTrue(absoluteFilePath2.ToString() == @"C:\DirA\DirC\File.txt");
var relativeFilePath2 = absoluteFilePath2.GetRelativePathFrom(absoluteDirectoryPath);
Assert.IsTrue(relativeFilePath2.Equals(relativeFilePath)); // Use Equals() for path comparison, dont use ==
var envVarFilePath = @"%ENVVAR%\DirB\File.txt".ToEnvVarFilePath();
Assert.IsTrue(envVarFilePath.EnvVar == "%ENVVAR%");
IAbsoluteFilePath absoluteFilePath3;
Assert.IsTrue(envVarFilePath.TryResolve(out absoluteFilePath3) == EnvVarPathResolvingStatus.ErrorUnresolvedEnvVar);
Environment.SetEnvironmentVariable("ENVVAR", @"NotAValidPath");
Assert.IsTrue(envVarFilePath.TryResolve(out absoluteFilePath3) == EnvVarPathResolvingStatus.ErrorEnvVarResolvedButCannotConvertToAbsolutePath);
Environment.SetEnvironmentVariable("ENVVAR", @"C:\DirA");
Assert.IsTrue(envVarFilePath.TryResolve(out absoluteFilePath3) == EnvVarPathResolvingStatus.Success);
Assert.IsTrue(absoluteFilePath3.ToString() == @"C:\DirA\DirB\File.txt");
Environment.SetEnvironmentVariable("ENVVAR", "");
var variableFilePath = @"$(VarA)\DirB\$(VarC)\File.txt".ToVariableFilePath();
Assert.IsTrue(variableFilePath.PrefixVariable == "VarA");
Assert.IsTrue(variableFilePath.AllVariables.First() == "VarA");
Assert.IsTrue(variableFilePath.AllVariables.ElementAt(1) == "VarC");
IAbsoluteFilePath absoluteFilePath4;
Assert.IsTrue(variableFilePath.TryResolve(
new KeyValuePair<string, string>[0],
out absoluteFilePath4) == VariablePathResolvingStatus.ErrorUnresolvedVariable);
Assert.IsTrue(variableFilePath.TryResolve(
new[] {new KeyValuePair<string, string>("VarA", "NotAValidPath"),
new KeyValuePair<string, string>("VarC", "DirC")},
out absoluteFilePath4) == VariablePathResolvingStatus.ErrorVariableResolvedButCannotConvertToAbsolutePath);
Assert.IsTrue(variableFilePath.TryResolve(
new[] {new KeyValuePair<string, string>("VarA", @"C:\DirA"),
new KeyValuePair<string, string>("VarC", "DirC")},
out absoluteFilePath4) == VariablePathResolvingStatus.Success);
Assert.IsTrue(absoluteFilePath4.ToString() == @"C:\DirA\DirB\DirC\File.txt");
Assert.IsTrue(@"C://DirA/\DirB//".ToDirectoryPath().ToString() == @"C:\DirA\DirB");
Assert.IsTrue(@"%ENVVAR%\DirA\..\DirB".ToDirectoryPath().ToString() == @"%ENVVAR%\DirB");
Assert.IsTrue(@".\..".ToDirectoryPath().ToString() == "..");
Assert.IsTrue(@".\..\.\Dir".ToDirectoryPath().ToString() == @"..\Dir");
IAbsoluteDirectoryPath commonRootDir;
Assert.IsTrue(new[] {
@"C:\Dir".ToAbsoluteDirectoryPath(),
@"C:\Dir\Dir1".ToAbsoluteDirectoryPath(),
@"C:\Dir\Dir2\Dir3".ToAbsoluteDirectoryPath(),
}.TryGetCommonRootDirectory(out commonRootDir));
Assert.IsTrue(commonRootDir.ToString() == @"C:\Dir");
Possibility to work with IFilePath IDirectoryPath and be abstracted from the underlying kind (Absolute/Relative/EnvVar/Variable)
foreach (var s in new[] {
@"C:\Dir\File.txt",
@"\\Server\Share\Dir\File.txt",
@"..\..\Dir\File.txt",
@"%ENVVAR%\Dir\File.txt",
@"$(Var)\Dir\File.txt",
}) {
var filePath = s.ToFilePath();
Assert.IsTrue(filePath.FileName == @"File.txt");
Assert.IsTrue(filePath.HasParentDirectory);
Assert.IsTrue(filePath.ParentDirectoryPath.DirectoryName == @"Dir");
}
IDirectoryPath directoryPath;
Assert.IsFalse(@"NotAValidPath".TryGetDirectoryPath(out directoryPath));
string failureReason;
Assert.IsFalse(@"NotAValidPath".IsValidDirectoryPath(out failureReason));
Assert.IsTrue(failureReason == @"The string ""NotAValidPath"" is not a valid directory path.");
Assert.IsFalse(@"C:".IsValidFilePath());
Assert.IsFalse(@"\\Server\Share".IsValidFilePath());
Assert.IsTrue(@"C:".IsValidDirectoryPath());
Assert.IsTrue(@"\\Server\Share".IsValidDirectoryPath());
Assert.IsTrue(@"C:\Dir".IsValidFilePath());
Assert.IsTrue(@"\\Server\Share\Dir".IsValidFilePath());
Assert.IsTrue(@"C:\Dir".IsValidDirectoryPath());
Assert.IsTrue(@"\\Server\Share\Dir".IsValidDirectoryPath());