-
Notifications
You must be signed in to change notification settings - Fork 129
Add new functionality and restrictions to #requires #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new functionality and restrictions to #requires #122
Conversation
One thing I would like clarified by the RFC is how it will interact with Linux shbang #!/usr/bin/env pwsh
#requires -OS Linux
# Some linux specific code I would like to ensure that is not broken. |
@markekraus Yes I had that specifically in mind. I will make the language more explicit. |
after will cause a parse-time error. This would be a **breaking | ||
change**, albeit one that the documentation already claims to be | ||
in force. | ||
* Using `#requires` in the interactive console will cause |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this provides any benefit, and I'm not aware of a straightforward way to implement it.
Today the engine knows nothing about interactive input - that's the domain of a host, but the host for the most part doesn't care what the input looks like.
One thought would be to only allow #requires
in a file, but that won't work in some important scenarios, e.g. Invoke-Command -File foo.ps1
sends the contents of the file to the remote session, but the remote session doesn't know about a file.
People also use Get-Content or Invoke-WebRequest piped to Invoke-Expression - again losing the fact that the input was really in a file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lzybkr You're referring to preventing #requires
in an interactive session here right? I'm not particularly invested in this feature, but saw PowerShell issue #3803 and implemented this PR which still throws an error. Thought I would include it in the RFC for the purposes of discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see - in that context, interactive == add to history. From the code, it's not obvious that it doesn't break the Invoke-Command
scenario I mentioned, nor is it obvious under what conditions one might invoke something adding to history where the command isn't actually interactive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right! Admittedly part of me thinks that piping into Invoke-Expression
is something we should discourage, but I suppose we shouldn't break it, and moreover that #requires
is probably more useful doing what it promises to do there. But good that I now understand the full context of the interactiveCommand
; I'll roll back a couple of those changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems there is some scenarios where "interactive" is important (ex.: don't load some modules). We already added -i
to be compatible with Bash. I'd want to get that the engine knows that the session is interactive.
Perhaps @mklement0 have more thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov - an interactive session is different than a command entered interactively.
Set-ExecutionPolicy is the only place in the engine that I know of that infers if the command is entered interactively and alters it's behavior accordingly.
any executable PowerShell code). Placing `#requires` anywhere | ||
after will cause a parse-time error. This would be a **breaking | ||
change**, albeit one that the documentation already claims to be | ||
in force. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion on introducing a breaking change, but I suppose some might see a benefit in putting #requires
elsewhere, e.g. at the bottom of the file, perhaps to somewhat hide what might seem like an unimportant implementation detail.
Instead of a breaking change, the documentation could be made clearer. The directive is not scoped - it applies to the outermost ScriptBlock in which the directive appears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not normative, just some history: Originally #requires had to be the first non-space non-comment line in the file. This is because we were asked to consider the case were we got the language sufficiently wrong that we had to introduce incompatible changes. In that scenario, #requires -version X might cause a different parser to be used for the file. (This feature, along with numbers in the extensions (.ps1), and snapins were all part of the pre v1 versioning reviews.) #requires was also done in a preprocessing phase, rather than as part of the main parse. I think @lzybkr changed this in the V3 parser rewrite.
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/3751). | ||
* `-Assembly <Assembly-name>`, where a .NET assembly can | ||
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/5022). | ||
* `-MaxVersion <V>[.<v>]`, where a maximum PowerShell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if we need a -MaxVersion
. The original issue was trying to differentiate Windows PowerShell and PowerShell Core. Since these changes wouldn't go down to Windows PowerShell, it seems to be of limited use to use -MaxVersion
to differentiate between the two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it does provide some benefit. Even though a version of PSCore is only supported for 18 months? scripts will be written in that time for that version. If we implement breaking changes in 6.3.0, a script written during 6.1.0's lifetime could put a max version of 6.1.0 in it to ensure that anyone running an older version of the script on a newer 6.3.0 version of pwsh, they will fail fast rather than risk potential broken behavior.
This goes to the larger discussion of how to deal with breaking changes, but I think this feature actually makes it possible to do them without major version madness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@markekraus for your scenario, it seems that an -ExactVersion would be more useful if you have business critical scripts that you want time to verify before moving to a newer version of PSCore6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-ExactVersion
would. for some instances. I think if we are committed to X.Y.Z versions where Z changes never include a breaking change, something that somehow limiting to a minor (Y) version would work and probably be what is desirable for most cases. Basically way to do (version >= 6.X.0 && version < 6.(X+1).0)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we say about business critical scripts I'd want to see error events in logs if the directive catch wrong version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we'll want the -MaxVersion
and -ExactVersion
I'd re-use -Version
with prefixes like <
,>
, ... - -Version <=6.1.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov That would definitely make it more flexible... but... something like -ExactVersion 6.0.2
and -MinorVersion 6.1
would cover probably most use cases (assuming we don't suddenly start making breaking changes in the PATCH level iterations)
console. | ||
3. `#requires` can take an `-OS` parameter, with possible | ||
arguments being `Windows`, `Linux` and `MacOS` (and | ||
possibly some syntax for `or`-ing them). This check |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably -OS Linux,macOS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use generic -OS Unix
for all supported Unixes?
And should we consider OS version? -OS Unix(Ubuntu 16.04)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Unix
as generic term for Linux
, Unix
, and macOS
is 1) not accurate and 2) really makes some people angry. 🙁 I would advise against anything Microsoft does making that mistake as it then makes MS look either ignorant or arrogant depending on what issue a person takes with that usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@markekraus: I think @iSazonov is suggesting Unix
as an additional identifier, to serve as an abstraction over macOS and Linux for scripts that run on both. Given that both platforms have a Unix heritage and many commonalities (especially in contrast with Windows), it is a useful abstraction. It is the case variant UNIX
that is trademarked; I think that the term Unix
to loosely refer to all platforms with a Unix heritage is well-established - see https://en.wikipedia.org/wiki/Unix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mklement0 Yes, and that usage is contentious to the point of being inflammatory. That's is why I'm recommending against it. I understood @iSazonov intent.
I'll also counter that it is not practical. My exposure to CoreFX is that macOS is it's own beast. That's not even considering the radically different ecosystem from Linux. The gap is wide enough that I see very few cases where Unix would be useful to mean not-windows
.
With that and the inflammatory nature a Microsoft product of using Unix
to lump them together further coupled with "there is nothing wrong with -OS Linux,macOS
" I'd say we shouldn't use it.
Though another category might be helpful: Windows
, Linux
, macOS
, IoT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@markekraus: Whether the abstraction is useful should be discussed separately from its name.
-
To me, the abstraction is useful (speaking as a shell user on both platforms) - it all depends on the use case (we're not talking system-level programs here); perhaps others can weigh in.
-
If the name
Unix
is really that contentious (which I'm personally not aware of), perhapsUnixLike
will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current .Net Core team support goal is "we should run on all platforms". So maybe we should use more generic parameter -OS
and sub-parameters for platform, version ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"UNIX" is a trademark. "UnixLike" doesn't address the aversion to "Unix", but maybe "LikeUnix" could be shortened to… "Linux".
I cannot agree that 'requires' statements should be allowed in scripts only - I personally find it very useful in functions |
I think we could keep scripts as simple as possible and not enhance this directive. |
Reviewed this one with @JamesWTruher and @SteveL-MSFT: we feel like To that end, the only ones we'd like to add is The only other open question is whether we enable loose validation of Still need quorum to close on this, though. |
I agree with the conclusion and I don't like to enhance #requires directive in future. |
The |
@brianary agreed, but that same problem would exist if we added that behavior here. @HemantMahawar suggested we alias We'll wait until we have post-snow quorum to wrap this up with a vote. :) |
It could, it just depends on how it's implemented. If the existing syntax
can't improve the performance due to backward compatibility issues, this
would provide an alternative. Maybe I need to open a separate issue to
address the performance.
…On Wed, Feb 13, 2019, 16:00 Joey Aiello ***@***.*** wrote:
@brianary <https://github.com/brianary> agreed, but that same problem
would exist if we added that behavior here.
@HemantMahawar <https://github.com/HemantMahawar> suggested we alias
-Version to -MinimumPSVersion for clarity, and then have -MaximumVersion
called -MaximumPSVersion ("maximum" for consistency with Import-Module).
We'll wait until we have post-snow quorum to wrap this up with a vote. :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#122 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AH8mJ49By6iMQaw_MARWyNLyvQnBaTRgks5vNKcBgaJpZM4S4QSQ>
.
|
@PowerShell/powershell-committee reviewed this and is fine with current proposal to alias for clarity and adding -OS and -MaximumPSVersion |
I've edited the RFC to adapt to the @PowerShell/powershell-committee's decisions. Please let me know if further edits are required |
* `-MinimumPSVersion` as an alias of `-MinimumVersion`. | ||
|
||
* **Withdrawn**, in favor of `using` statements. | ||
~~`-Assembly <Assembly-name>`, where a .NET assembly can |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just kept it for context. Happy to remove if that's better. Or add a Withdrawn
section to contain these things
Per @SteveL-MSFT 's request, can you move all the withdrawn stuff to an "Alternate Considerations" section near the bottom, along with explanation of what it is that was rejected/withdrawn? |
@joeyaiello @SteveL-MSFT @PowerShell/powershell-committee This has now been updated to comply with the request above |
No description provided.