diff --git a/install.ps1 b/install.ps1 index 5ba1d7ae..8bb01c51 100644 --- a/install.ps1 +++ b/install.ps1 @@ -3,12 +3,11 @@ # Everything runs in a script block of its own: piped into iex, the script # would otherwise leave its variables and $ErrorActionPreference = "Stop" # in the user's session, where every later error would stop their commands. +# Neither the script nor the block declares a parameter: one [Parameter()] +# attribute makes it an advanced one, whose common parameters took -v +# (-Verbose), -vb, -d (-Debug) and -ea before install.py could see them. & { - [CmdletBinding()] - param( - [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$InstallerArguments - ) + $InstallerArguments = @($args) $ErrorActionPreference = "Stop" $defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py" diff --git a/tests/test_install.py b/tests/test_install.py index c1753935..49b949c7 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -2276,6 +2276,29 @@ class ThePowerShellWrapperPassesTheStatusOn(unittest.TestCase): self.assertNotIn("installer failed", proc.stdout + proc.stderr) +class ThePowerShellWrapperPassesEveryArgument(unittest.TestCase): + """A [Parameter()] attribute made install.ps1 an advanced script, whose + common parameters took -v (as -Verbose), -vb, -d and -ea: the documented + `-v` never reached install.py.""" + + @unittest.skipUnless(shutil.which("pwsh"), "needs PowerShell") + def test_short_flags_reach_the_installer(self): + folder = Path(_tempdir(self)) + shutil.copy(REPO_ROOT / "install.ps1", folder / "install.ps1") + (folder / "install.py").write_text( + "import json, sys\nprint(json.dumps(sys.argv[1:]))\n" + ) + for args in (["-v", "--check"], ["-vb"], ["-Verbose"], ["-d", "-ea", "x"], + ["--platform", "a b"], []): + with self.subTest(args=args): + proc = subprocess.run( + ["pwsh", "-NoProfile", "-File", str(folder / "install.ps1"), *args], + capture_output=True, text=True, timeout=120, + ) + self.assertEqual(proc.returncode, 0, proc.stderr) + self.assertEqual(json.loads(proc.stdout), args) + + @unittest.skipIf(os.name == "nt" or os.geteuid() == 0, "needs a folder this user cannot write") class AnUnwritableFolderIsCodeTwo(unittest.TestCase): """A BIOS folder that could not be created ended with 1, while the same diff --git a/wiki/installer.md b/wiki/installer.md index 862571ed..c8349519 100644 --- a/wiki/installer.md +++ b/wiki/installer.md @@ -510,7 +510,9 @@ fields, the installer refuses to narrow rather than install everything. `install.ps1` passes the installer's code on unchanged: run as a file it exits with it, run through `irm \| iex` it sets `$LASTEXITCODE` (an `exit` there -would close the PowerShell window). Its body runs in a script block of its own, +would close the PowerShell window). It declares no parameter of its own, so +every argument reaches `install.py` as typed, short forms such as `-v` +included. Its body runs in a script block of its own, so `irm \| iex` leaves neither its variables nor its `$ErrorActionPreference` in the session.