@@ -33,33 +33,40 @@ executed, no matter where they are placed.
3333
3434This 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
127116Finally, scripts with ` #requires ` in them should still
128117be 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