Powershell: Convert-Path should work with non-existent paths

Created on 11 Jan 2017  路  15Comments  路  Source: PowerShell/PowerShell

It seem clear to me that a design mistake was made when Resolve-Path and Convert-Path were created, and they both return only resolved paths (i.e. the path must exist).

The right design would be to have Convert-Path not care if the path exists, and if you care, you use both commands.

Since that ship has sailed, I propose adding a -Unresolved switch to Convert-Path to change it to do what it should have done all along, called GetUnresolvedProviderPathFromPSPath instead of calling GetResolvedProviderPathFromPSPath.

If nobody has a problem with that ... I can send a PR

Area-Cmdlets Committee-Reviewed Issue-Enhancement

Most helpful comment

Thanks, @SteveL-MSFT, but there's also this:

PS> Get-ParameterVerb No

Verb Group  Description
---- -----  -----------
No   Common Opts out of a default behavior.

Granted, _no_ is not a _verb_, but neither are new, foreach, or where - close enough.

And, from the associated help topic:

Verb | Action | Comments
-----| -------| ----------------
No | Opts out of a default behavior. | For this action, do not use verbs such as Skip, Omit, Bypass, or Drop

Now, you might argue that this is just fan fiction - and you'd be correct - but isn't it a great story?

All 15 comments

Great! Make PR.
I'd only made the switch more descriptive: -UnresolvePath?

I'd suggest something along the lines of -SkipPathCheck similar to the other Skip switches as mentioned in #2006

Perhaps @rkeithhill will again offer a good option.

@SteveL-MSFT @mklement0 Can we approve the new behavior and parameter?

The new behavior behind a switch seems fine. cc @HemantMahawar if he has any good suggestions on naming.

Opting out of behavior is more typically done with -No* parameters (-NoNewline, -NoProxy, -NoClobber, ... - Get-Module and Invoke-WebRequest/RestMethod are, unfortunately, dissenters and use -Skip*)

Therefore: -NoResolve, perhaps?

TBH, -Skip<Something> and -No<Something> are very close, although have very subtle difference.

  • -Skip<Something> used in cmdlets ((SkipCertificateCheck, SkipEditionCheck, SkipHeaderValidation, SkipNetworkProfileCheck, SkipCACheck, SkipCNCheck, SkipRevocationCheck) ) is typically for bypassing some check.

  • -No<Something> used in cmdlets ((NoClobber, NoNewline, NoServiceRestart, NoTypeInformation, NoProxy, NoRecurse, NoQualifier, NoNewWindow, NoNewScope, NoMachineProfile, NoEnumerate, NoEncryption, NoElement, NoCompression, NoWait)) is typically about not taking specific action.

    In this case -SkipPathCheck (or maybe -SkipPathResolution or -SkipPathValidation) seems more appropriate.

```

Thanks, @HemantMahawar, I see the difference, but I personally don't think it's strong enough to warrant reflection in distinct parameter names.

Case in point: You could equally argue that the requested behavior here is _not taking the action_ of resolving the path.

To put it differently: I think the existing -Skip* parameters should have been named -No* instead to begin with for consistency (though, should we reach a consensus, we could introduce _aliases_ for consistency going forward).

A couple more thoughts: No is shorter and less ambiguous than Skip, which:

  • has plausible synonyms such as "bypass", "omit", ...
  • is also in use with significantly different semantics (
    Import-Cli -Skip <int>, Select-Object -Skip <int> -SkipLast <int> -SkipIndex <int[]>)

@PowerShell/powershell-committee reviewed this and recommends -SkipValidation

@SteveL-MSFT: While I see value in the generic aspect of the Validation part of the parameter name, can you explain why the Skip part was considered worth retaining?

In other words: what is the value in retaining the -No* / -Skip* split?

@mklement0 it's unfortunate that we have some inconsistency, however, in discussing this specific issue, we agreed that Skip was more readable than No as in: Convert-Path foo -SkipValidation was slightly more understandable as English than Convert-Path foo -NoValidation

Thanks, @SteveL-MSFT, but there's also this:

PS> Get-ParameterVerb No

Verb Group  Description
---- -----  -----------
No   Common Opts out of a default behavior.

Granted, _no_ is not a _verb_, but neither are new, foreach, or where - close enough.

And, from the associated help topic:

Verb | Action | Comments
-----| -------| ----------------
No | Opts out of a default behavior. | For this action, do not use verbs such as Skip, Omit, Bypass, or Drop

Now, you might argue that this is just fan fiction - and you'd be correct - but isn't it a great story?

It seems like the guidance for inverted parameter switches should be along the lines of:

  • No (Additional Output or Tasks) -- also, use to invert a verb switch
  • Skip (Additional Tests or Validation)

For what it's worth, if this was being written from scratch, I could see either -NoValidate or -SkipValidation but ...

  1. It needed to be -NoValidate (an inversion of a hypothetical -Validate verb switch), because "Validation" is a noun
  2. In greenfield, we would hopefully have said: change the default behavior, and use -Resolve as the switch 馃槈

Given the cmdlet has existed, doing what it does, for years, "skip"ing what it normally does makes sense to me.

I liked using "Resolve" in there (-NoResolve ??) rather than validate, because under the covers (and in other cmdlets) that's what we call it. Additionally, we're not (just) skipping validation, we're going to not "resolve" the path to an existing folder -- which means that if we're passed a path with wildcards, we would return a path that still has wildcards in it, right?

which means that if we're passed a path with wildcards, we would return a path that still has wildcards in it, right?

Yes - to me that's the only sensible action to take.

Re -NoValidation vs. -NoValidate: To me, the No is the "verb" in this name and that goes better with a noun; that said, I don't feel strongly about this aspect (the existing -No* parameters show both patterns) - unlike the aspect of keeping the -Skip* / -No* dichotomy (see below).

Actually, I just realized that I had accidentally created duplicate issue #7197, where I had suggested -NoCheck as the switch name.

The naming issue aside, the linked issue also proposes adding a -PSProvider argument, so that scripts can robustly refer to the current _filesystem_ location, even if a different provider happens to underlie the current location.


Re -Skip* vs. -No*, for the love of Snover and punishing perished ponies:

  • The distinction between -Skip* and -No* is arbitrary and not rooted in real-world semantics. There's nothing inherent in the common usage of the verb _to skip_ that ties it to validation or checks.

  • As such, it offers no benefit and introduces extrinsic complexity.

    • The aspect of whether consistently applied -No* naming relates to a check or an action in a given parameter can be inferred from the parameter's full name itself.
Was this page helpful?
0 / 5 - 0 ratings