@@ -33,33 +33,40 @@ executed, no matter where they are placed.
33
33
34
34
This RFC proposes the following changes:
35
35
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,
37
52
before any lines that are not comments (i.e. with the
38
53
intention that a hashbang can still work, just before
39
54
any executable PowerShell code). Placing ` #requires ` anywhere
40
55
after will cause a parse-time error. This would be a ** breaking
41
56
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
44
61
a parse-time error. This could be a ** minor breaking
45
62
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 ) .~~
56
64
57
65
## Motivation
58
66
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.
63
70
64
71
> As a PowerShell user, I get feedback that ` #requires `
65
72
> statements cannot be used in the interactive console,
@@ -72,12 +79,6 @@ This RFC proposes the following changes:
72
79
> guarantee that it is used only on systems I designed it
73
80
> for.
74
81
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
-
81
82
> As a PowerShell user, I can specify that my script
82
83
> ` #requires ` to be run in a version of PowerShell
83
84
> lower than a given version, so that I can declaratively
@@ -86,43 +87,31 @@ This RFC proposes the following changes:
86
87
87
88
## Specification
88
89
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
109
105
a pre-execution error with a specific error message
110
106
stating that the script is required to be run on a
111
107
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.
126
115
127
116
Finally, scripts with ` #requires ` in them should still
128
117
be editable in contexts that do not satisfy their
@@ -133,8 +122,8 @@ PowerShell issue](https://github.com/PowerShell/PowerShell/issues/4549).
133
122
134
123
## Alternate Proposals and Considerations
135
124
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> ` .~~
138
127
* Given the suite of proposed changes to ` #requires ` , any
139
128
other proposed parameters for ` #requires ` are worth
140
129
including and discussing in this RFC. Possible
@@ -150,6 +139,3 @@ PowerShell issue](https://github.com/PowerShell/PowerShell/issues/4549).
150
139
currently [ undocumented] ( https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires?view=powershell-6 ) and
151
140
there is an [ open issue for it] ( https://github.com/PowerShell/PowerShell/issues/5908 ) . It may
152
141
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