Skip to content

Commit e833578

Browse files
author
Robert Holt
committed
Edit RFC inline with committee ruling
1 parent 070e0db commit e833578

File tree

1 file changed

+48
-62
lines changed

1 file changed

+48
-62
lines changed

1-Draft/RFCNNNN-#Requires-Additions.md

Lines changed: 48 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,40 @@ executed, no matter where they are placed.
3333

3434
This RFC proposes the following changes:
3535

36-
* Only allow `#requires` at the top level of a script,
36+
* Emit a warning when parsing scripts where the `#requires`
37+
is not at the top, because of the hoisting behavior.
38+
* Add support for the following new parameters (each
39+
independently up for discussion):
40+
* `-OS {Windows | Linux | MacOS}`, where an
41+
operating system (or possibly combination of them) can
42+
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/3751).
43+
* `-MaximumPSVersion <V>[.<v>]`, where a maximum PowerShell
44+
version can be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/2846).
45+
* `-MinimumPSVersion` as an alias of `-MinimumVersion`.
46+
47+
* **Withdrawn**, in favor of `using` statements.
48+
~~`-Assembly <Assembly-name>`, where a .NET assembly can
49+
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/5022).~~
50+
* **Withdrawn** on the basis that this could break many existing scripts.
51+
~~Only allow `#requires` at the top level of a script,
3752
before any lines that are not comments (i.e. with the
3853
intention that a hashbang can still work, just before
3954
any executable PowerShell code). Placing `#requires` anywhere
4055
after will cause a parse-time error. This would be a **breaking
4156
change**, albeit one that the documentation already claims to be
42-
in force.
43-
* Using `#requires` in the interactive console will cause
57+
in force.~~
58+
* **Withdrawn** since this is difficult to implement with little gain
59+
and it breaks the layering of the parser.
60+
~~Using `#requires` in the interactive console will cause
4461
a parse-time error. This could be a **minor breaking
4562
change**, since currently PowerShell throws a [pipeline
46-
creation error](https://github.com/PowerShell/PowerShell/issues/3803).
47-
* Add support for the following new parameters (each
48-
independently up for discussion):
49-
* `-OS {Windows | Linux | MacOS}`, where an
50-
operating system (or possibly combination of them) can
51-
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/3751).
52-
* `-Assembly <Assembly-name>`, where a .NET assembly can
53-
be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/5022).
54-
* `-MaxVersion <V>[.<v>]`, where a maximum PowerShell
55-
version can be specified as required. See [this PowerShell issue](https://github.com/PowerShell/PowerShell/issues/2846).
63+
creation error](https://github.com/PowerShell/PowerShell/issues/3803).~~
5664

5765
## Motivation
5866

59-
> As a PowerShell user, I can be sure that all the
60-
> `#requires` statements in a script come before any
61-
> PowerShell code, so that it's clear they always
62-
> execute first, and so they can all be found easily.
67+
> As a PowerShell user, I will be warned about
68+
> `#requires` statements that won't behave the
69+
> way I might expect based on position.
6370
6471
> As a PowerShell user, I get feedback that `#requires`
6572
> statements cannot be used in the interactive console,
@@ -72,12 +79,6 @@ This RFC proposes the following changes:
7279
> guarantee that it is used only on systems I designed it
7380
> for.
7481
75-
> As a PowerShell user, I can specify that my script
76-
> `#requires` a given .NET Assembly to run in an
77-
> efficient and declarative way, so that I don't have
78-
> to do complex runtime logic to determine my script
79-
> cannot run.
80-
8182
> As a PowerShell user, I can specify that my script
8283
> `#requires` to be run in a version of PowerShell
8384
> lower than a given version, so that I can declaratively
@@ -86,43 +87,31 @@ This RFC proposes the following changes:
8687
8788
## Specification
8889

89-
1. `#requires` statements must appear in scripts
90-
above all executable PowerShell. Any `#requires`
91-
statement placed after any PowerShell code causes
92-
an unrecoverable parse-time error. This new restriction
93-
should not affect the usage of other comment-embedded
94-
directives or pragmas, such as `#sig`, linter directives or
95-
inline editor configurations. Specifically, the new `#requires`
96-
placement restriction must not interfere with Unix-style
97-
hashbangs (e.g. `#!/usr/bin/pwsh`).
98-
2. Any use of `#requires` in an interactive session causes
99-
a specific parse-time error to be thrown, informing the
100-
user that `#requires` may not be used in the interactive
101-
console.
102-
3. `#requires` can take an `-OS` parameter, with possible
103-
arguments being `Windows`, `Linux` and `MacOS` (and
104-
possibly some syntax for `or`-ing them). This check
105-
succeeds if-and-only-if the correspoding runtime
106-
PowerShell variable (`$IsWindows`, `$IsLinux` and
107-
`$IsMacOS` is true). Requiring a given OS when the
108-
corresponding runtime variable is false results in
90+
1. `#requires` statements appearing before any
91+
line that is not blank or a comment (i.e. any semantic statement)
92+
will generate a warning at parse-time about being hoisted to the top of the script.
93+
Other comments, such as hashbangs, and blank lines
94+
preceing a `#requires` will not generate this warning.
95+
2. `#requires` can take an `-OS` parameter,
96+
with possible arguments being `Windows`, `Linux` and `MacOS`.
97+
Multiple operating systems can be specified by providing arguments
98+
in an array syntax, such as `#requires -OS 'Linux','MacOS'`,
99+
with the meaning of **any** of the required operating systems.
100+
The check for a given operating system succeeds
101+
if-and-only-if the correspoding runtime PowerShell variable
102+
(`$IsWindows`, `$IsLinux` and `$IsMacOS`)
103+
executed on that system would be true.
104+
Requiring a given OS when the corresponding runtime variable is false results in
109105
a pre-execution error with a specific error message
110106
stating that the script is required to be run on a
111107
different operating system.
112-
4. `#requires` can take an `-Assembly` parameter, with
113-
possible arguments being exactly what a `using assembly`
114-
statement will accept. If a required assembly is not
115-
present on the executing system, a pre-execution error
116-
is raised.
117-
5. `#requires` can take a `-MaxVersion` parameter, with
118-
a major version and optional minor version, to define
119-
the maximum (inclusive) version of PowerShell it should
120-
run on. The version given does not need to correspond to
121-
any version of PowerShell, but will just be compared in
122-
standard lexicographic tuple order. Executing a script
123-
required to be on a version of PowerShell strictly lower
124-
than the executing version results in a pre-execution
125-
error.
108+
3. `#requires` can take a `-MaximumPSVersion` parameter,
109+
with a major version and optional minor version,
110+
to define the maximum (inclusive) version of PowerShell it should run on.
111+
The version given does not need to correspond to any existing version of PowerShell,
112+
but will be compared in standard PowerShell version comparison logic.
113+
Executing a script required to be on a version of PowerShell strictly lower
114+
than the executing version results in a pre-execution error.
126115

127116
Finally, scripts with `#requires` in them should still
128117
be editable in contexts that do not satisfy their
@@ -133,8 +122,8 @@ PowerShell issue](https://github.com/PowerShell/PowerShell/issues/4549).
133122

134123
## Alternate Proposals and Considerations
135124

136-
* An `-Assembly` parameter may be unneccessary, given the
137-
possibility of using `using assembly <Assembly-name>`.
125+
* **Withdrawn**. ~~An `-Assembly` parameter may be unneccessary, given the
126+
possibility of using `using assembly <Assembly-name>`.~~
138127
* Given the suite of proposed changes to `#requires`, any
139128
other proposed parameters for `#requires` are worth
140129
including and discussing in this RFC. Possible
@@ -150,6 +139,3 @@ PowerShell issue](https://github.com/PowerShell/PowerShell/issues/4549).
150139
currently [undocumented](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires?view=powershell-6) and
151140
there is an [open issue for it](https://github.com/PowerShell/PowerShell/issues/5908). It may
152141
be worth discussing in this RFC.
153-
* Because of the pipeline-crash behavior of the interactive
154-
usage of `#requires`, there is already a PR open to change
155-
the behavior to what is described in this RFC.

0 commit comments

Comments
 (0)