Violation of the (great) separation of concerns design principle in Join-Path
See original GitHub issueGood evening
it’s really hard to complain this issue because it’s a discussion about the most basic design principles we know and love snce many years:
Functions (in PowerShell commands) should never do things which the user does not expect. Such things are well known as side-effects and we had to fight with them 20 years ago as Spaghetti code was widely used.
Therefore it hurts to see that those Problems are comming back.
The concrete problem: Join-Path does no longer solve the problem which we expect (join path items), but it also checks if a drive exists.
The essence behind this “logic” is that no one is joining path items with non existing drive letters. Of course, this is wrong. But to get a consitent logic, the next version of Join-Path must automatically create any non-exsting path - it’s the same logic: no one is joining path items with a non existing path.
Beside the inconsistent logic, we have more very annoying side effects:
- Existing Code no longer works
- Users are searching for functions which are solvong the problem to join path items
- If someone is writing a function which is just joining path items - how should it get called? Join-Path-Without-Test? maybe Just-Join-Path? Of course, it must be called Join-Path.
There are many better options to handle the Problem, for example:
- Add a Parameter (e.g. -AssertDrive and -EnforceDir), but don’t change the default logic because it is already perfect
- Create another function, e.g. Join-Path-Assert
- Pass the result of Join-Path to a function which is testing if the drive exists
Kind regards, Thomas
Steps to reproduce
# If the Drive Q: does not exists:
PS C:\Users\schittli> Join-Path 'q:\' 'test'
Join-Path : Cannot find drive. A drive with the name 'q' does not exist.
Expected behavior
Join-Path ist doing what we expect: join path Elements. Nothing else.
Actual behavior
Join-Path has an enforced side-effect and it does break the separation of concerns design principle
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14393.1480
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.1480
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Issue Analytics
- State:
- Created 6 years ago
- Reactions:12
- Comments:14 (12 by maintainers)
@PowerShell/powershell-committee reviewed this. Expectation is that if given a drive that exists, it should use that provider’s path separator. If given a drive does not exist, then it will default to the current provider’s path separator. An additional
-Provider
parameter may be added to allow specifying an explicit provider (this should be a separate issue).This came up in documentation discussions, I would naively propose that, if the PSDrive can’t be resolved, that we fall back to default filesystem path separators for the given platform.
This would fall in line with what we do with non-drive
Join-Path
calls:Thoughts?