Skip to content

Commit

Permalink
(ForNeVeR#18) IPath.Parent: document the current solution
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Sep 22, 2024
1 parent 0d75cad commit edb444f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- [#18](https://github.com/ForNeVeR/TruePath/issues/18): update to behavior of `.Parent` on relative paths.

Now, it works for relative paths by either removing the last part or adding `..` as necessary to lead to a parent directory.

Thanks to @Kataane.

## [1.4.0] - 2024-08-12
### Changed
- [#16: Support Windows disk drives in the normalization algorithm](https://github.com/ForNeVeR/TruePath/issues/16).
Expand Down
27 changes: 16 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,28 @@ This is an interface that is implemented by both `LocalPath` and `AbsolutePath`.
This is a marker type that doesn't offer any advanced functionality over the contained string. It is used to mark paths that include wildcards, for further integration with external libraries, such as [Microsoft.Extensions.FileSystemGlobbing][file-system-globbing.nuget].

### Path Features
Aside from the strict types, the following features are supported for the paths:
- `IPath::Value` returns the normalized path string;
- `IPath::FileName` returns the last component of the path;
- `IPath::Parent` returns the parent path item (`null` for the root path or top-level relative path);
- `IPath<T>` supports operators to join it with `LocalPath` or a `string` (note that in both cases appending an absolute path to path of another kind will take over: the last absolute path in chain will win and destroy all the previous ones; this is the standard behavior of path-combining methods — use `AbsolutePath` in combination with `RelativePath` if you want to avoid this behavior);
- `IPath::IsPrefixOf` to check path prefixes;
- `IPath::StartsWith` to check if the current path starts with a specified path;
- `AbsolutePath::ReadKind` helps to check if a path exists, and if it is, then what kind of path it is (file, directory, or something else);
Aside from the strict types, the following features are supported for the paths.

- `IPath::Value` returns the normalized path string.
- `IPath::FileName` returns the last component of the path.
- `IPath::Parent` returns the parent path item (`null` for the root absolute path).

Note that it will _always_ return a meaningful parent for a relative path: parent for `.` is `..`, parent for `..` is `../..`.

This means that generally `.Parent` behaves the same as appending a `..` component to the end of the path would. Also, this allows for an interesting property that `a / b.Parent.Value` is always the same as `(a / b).Parent` and `a / b / ".."` — in cases when this yield no exceptions, at least.
- `IPath<T>` supports operators to join it with `LocalPath` or a `string` (note that in both cases appending an absolute path to path of another kind will take over: the last absolute path in chain will win and destroy all the previous ones; this is the standard behavior of path-combining methods — use `AbsolutePath` in combination with `RelativePath` if you want to avoid this behavior).
- `IPath::IsPrefixOf` to check path prefixes.
- `IPath::StartsWith` to check if the current path starts with a specified path.
- `AbsolutePath::ReadKind` helps to check if a path exists, and if it is, then what kind of path it is (file, directory, or something else).
- `AbsolutePath::Canonicalize` to convert the path to the correct case on case-insensitive file systems, resolve symlinks.
- `LocalPath::IsAbsolute` to check the path kind (since it supports both kinds);
- `LocalPath::IsAbsolute` to check the path kind (since it supports both kinds).
- `LocalPath::ResolveToCurrentDirectory`: effectively calculates `currentDirectory / this`. No-op for paths that are already absolute (aside from converting to the `AbsolutePath` type).
- `AbsolutePath::RelativeTo`, `LocalPath::RelativeTo` to get a relative part between two paths, if possible;
- `AbsolutePath::RelativeTo`, `LocalPath::RelativeTo` to get a relative part between two paths, if possible.
- extension methods on `IPath`:
- `GetExtensionWithDot` and `GetExtensionWithoutDot` to get the file extension with or without the leading dot (note that `GetExtensionWithDot` will behave differently for paths ending with dots and paths without dot at all);
- `GetFileNameWithoutExtension` to get the file name without the extension (and without the trailing dot, if any)

(Note how `GetFileNameWithoutExtension()` works nicely together with `GetExtensionWithDot()` to reconstruct the resulting path from their concatenation, however weird the initial name was — no extension, trailing dot, no base name.)
(note how `GetFileNameWithoutExtension()` works nicely together with `GetExtensionWithDot()` to reconstruct the resulting path from their concatenation, however weird the initial name was — no extension, trailing dot, no base name).

### `Temporary`

Expand Down
5 changes: 3 additions & 2 deletions TruePath/IPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public interface IPath
string FileName { get; }

/// <summary>
/// The parent of this path. Will be <c>null</c> for a rooted absolute path, or relative path pointing to the
/// current directory.
/// The parent of this path. Will be <c>null</c> for a rooted absolute path. For a relative path, will always
/// resolve to its parent directory — by either removing directories from the end of the path, or appending
/// <code>..</code> to the end.
/// </summary>
IPath? Parent { get; }
}
Expand Down

0 comments on commit edb444f

Please sign in to comment.