Repository navigation
feat(generate): write Windows launchers beside generated stubs #11888
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| Describe 'task-stubs' { | ||
| BeforeAll { | ||
| $originalPath = Get-Location | ||
| # The workflow sets this for the whole job and Pester runs every suite in one process, so | ||
| # put back what was there rather than dropping it. | ||
| $originalTrustedConfigPaths = [Environment]::GetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', 'Process') | ||
| Set-Location TestDrive: | ||
| $env:MISE_TRUSTED_CONFIG_PATHS = $TestDrive | ||
|
|
||
| @' | ||
| [tasks.hello] | ||
| run = "echo hi-from-task" | ||
|
|
||
| [tasks."build:all"] | ||
| run = "echo hi-from-nested" | ||
| '@ | Out-File -FilePath 'mise.toml' -Encoding utf8NoBOM | ||
|
|
||
| mise generate task-stubs | Out-Null | ||
| } | ||
|
|
||
| AfterAll { | ||
| Set-Location $originalPath | ||
| if ($null -eq $originalTrustedConfigPaths) { | ||
| Remove-Item -Path Env:\MISE_TRUSTED_CONFIG_PATHS -ErrorAction SilentlyContinue | ||
| } else { | ||
| [Environment]::SetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', $originalTrustedConfigPaths, 'Process') | ||
| } | ||
| } | ||
|
|
||
| It 'writes a .cmd launcher beside each stub' { | ||
| # Windows will not execute the `#!/bin/sh` stub, so without this there is nothing to run. | ||
| Test-Path 'bin\hello' | Should -BeTrue | ||
| Test-Path 'bin\hello.cmd' | Should -BeTrue | ||
| (Get-Content 'bin\hello.cmd' -Raw) | Should -BeLike '*"mise" run "hello" %`**' | ||
| # Ownership marker: what regeneration and cleanup use to tell our file from the user's. | ||
| (Get-Content 'bin\hello.cmd' -Raw) | Should -BeLike '*rem generated by mise*' | ||
| } | ||
|
|
||
| It 'refuses to overwrite a hand-written launcher' { | ||
| New-Item -ItemType Directory -Force 'owned-bin' | Out-Null | ||
| "@echo off`r`necho mine`r`n" | Out-File -FilePath 'owned-bin\hello.cmd' -Encoding utf8NoBOM -NoNewline | ||
| mise generate task-stubs --dir owned-bin 2>&1 | Out-String | | ||
| Should -BeLike '*is not a generated launcher*' | ||
| (Get-Content 'owned-bin\hello.cmd' -Raw) | Should -BeLike '*echo mine*' | ||
| # Validation runs before anything is written, so the stub is not there either. | ||
| Test-Path 'owned-bin\hello' | Should -BeFalse | ||
| } | ||
|
|
||
| It 'runs the task through the launcher' { | ||
| # The point of the change: not that the file exists, but that it works. | ||
| & '.\bin\hello.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-task' | ||
| } | ||
|
|
||
| It 'covers nested tasks too' { | ||
| Test-Path 'bin\build\all.cmd' | Should -BeTrue | ||
| & '.\bin\build\all.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-nested' | ||
| } | ||
|
|
||
| It 'forwards arguments' { | ||
| @' | ||
| [tasks.echoer] | ||
| run = "echo got" | ||
| '@ | Out-File -FilePath 'mise.toml' -Encoding utf8NoBOM -Append | ||
| mise generate task-stubs | Out-Null | ||
| & '.\bin\echoer.cmd' extra | Select-Object -Last 1 | Should -BeLike '*extra*' | ||
| } | ||
|
|
||
| It 'is idempotent' { | ||
| # Regeneration walks the existing stub tree and refuses anything it did not write, so the | ||
| # launchers have to be recognised as generated or the second run fails. | ||
| mise generate task-stubs | Out-Null | ||
| mise generate task-stubs | Out-Null | ||
| Test-Path 'bin\hello.cmd' | Should -BeTrue | ||
| & '.\bin\hello.cmd' | Select-Object -Last 1 | Should -Be 'hi-from-task' | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| Describe 'tool-stub' { | ||
| BeforeAll { | ||
| $originalPath = Get-Location | ||
| # The test workflow sets MISE_TRUSTED_CONFIG_PATHS for the whole job, and Pester runs every | ||
| # suite in one process, so dropping it here would take it away from the files that run | ||
| # after this one. Put back what was there instead. | ||
| $originalTrustedConfigPaths = [Environment]::GetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', 'Process') | ||
| Set-Location TestDrive: | ||
| $env:MISE_TRUSTED_CONFIG_PATHS = $TestDrive | ||
|
|
||
| # Shared here rather than built up across It blocks, so any one of them can be run alone | ||
| # with `run.ps1 -TestName`. | ||
| @' | ||
| #!/usr/bin/env -S mise tool-stub | ||
| tool = "aqua:jqlang/jq" | ||
| version = "1.7.1" | ||
| bin = "jq" | ||
| '@ | Out-File -FilePath 'jqstub' -Encoding utf8NoBOM | ||
| mise generate tool-stub jqstub --fetch | Out-Null | ||
| } | ||
|
|
||
| AfterAll { | ||
| Set-Location $originalPath | ||
| if ($null -eq $originalTrustedConfigPaths) { | ||
| Remove-Item -Path Env:\MISE_TRUSTED_CONFIG_PATHS -ErrorAction SilentlyContinue | ||
| } else { | ||
| [Environment]::SetEnvironmentVariable('MISE_TRUSTED_CONFIG_PATHS', $originalTrustedConfigPaths, 'Process') | ||
| } | ||
| } | ||
|
|
||
| It 'writes a .cmd launcher beside the stub' { | ||
| # Windows cannot execute the stub itself -- it is a shebang script, which CreateProcess | ||
| # refuses -- so the generator has to leave something Windows will launch. | ||
| mise generate tool-stub plainstub --url 'https://example.com/thing.tar.gz' --skip-download | Out-Null | ||
| Test-Path 'plainstub' | Should -BeTrue | ||
| Test-Path 'plainstub.cmd' | Should -BeTrue | ||
| # %~dpn0, not the stub name: the launcher derives the path from its own filename, which is | ||
| # what keeps a name containing `%` from being mangled by cmd.exe. | ||
| (Get-Content 'plainstub.cmd' -Raw) | Should -BeLike '*mise tool-stub "%~dpn0" %`**' | ||
| } | ||
|
|
||
| It 'omits the launcher for a stub that does not ship for Windows' { | ||
| # The counterpart to the test above: without this one, a launcher written unconditionally | ||
| # would look just as correct. | ||
| mise generate tool-stub unixonly --skip-download ` | ||
| --platform-url 'linux-x64:https://example.com/tool-linux.tar.gz' ` | ||
| --platform-url 'macos-arm64:https://example.com/tool-macos.tar.gz' | Out-Null | ||
| Test-Path 'unixonly' | Should -BeTrue | ||
| Test-Path 'unixonly.cmd' | Should -BeFalse | ||
| } | ||
|
|
||
| It 'writes the launcher when the stub names a Windows platform' { | ||
| mise generate tool-stub crossplat --skip-download ` | ||
| --platform-url 'linux-x64:https://example.com/tool-linux.tar.gz' ` | ||
| --platform-url 'windows-x64:https://example.com/tool-windows.zip' | Out-Null | ||
| Test-Path 'crossplat.cmd' | Should -BeTrue | ||
| } | ||
|
|
||
| It 'runs a real tool through the generated launcher' { | ||
| # The point of the whole change: the stub is launchable from PowerShell/cmd. Uses a real | ||
| # tool rather than a dummy URL so this exercises install + execute, not just file creation. | ||
| Test-Path 'jqstub.cmd' | Should -BeTrue | ||
| & '.\jqstub.cmd' --version | Select-Object -Last 1 | Should -BeLike 'jq-1.7.1*' | ||
| } | ||
|
|
||
| It 'gives the same result through mise tool-stub directly' { | ||
| # The explicit invocation already worked before this change; keep it that way. | ||
| mise tool-stub jqstub --version | Select-Object -Last 1 | Should -BeLike 'jq-1.7.1*' | ||
| } | ||
|
|
||
| It 'runs a stub whose name contains a percent sign' { | ||
| # A batch file drops `%x` when x is not a parameter, so a launcher that spelled the stub | ||
| # name out would compute `jqstub` for this file and fail to find it. Deriving the path from | ||
| # the launcher's own filename with %~dpn0 sidesteps that. | ||
| # | ||
| # One `%`, not a `%VAR%` pair: cmd.exe expands pairs in the path it is handed, so a stub | ||
| # named `jq%PATH%stub` cannot be launched at all, whatever its launcher contains. | ||
| @' | ||
| #!/usr/bin/env -S mise tool-stub | ||
| tool = "aqua:jqlang/jq" | ||
| version = "1.7.1" | ||
| bin = "jq" | ||
| '@ | Out-File -FilePath 'jq%stub' -Encoding utf8NoBOM | ||
| mise generate tool-stub 'jq%stub' --fetch | Out-Null | ||
| Test-Path 'jq%stub.cmd' | Should -BeTrue | ||
|
|
||
| & '.\jq%stub.cmd' --version | Select-Object -Last 1 | Should -BeLike 'jq-1.7.1*' | ||
| } | ||
|
|
||
| It 'removes its own launcher when the stub stops shipping for Windows' { | ||
| mise generate tool-stub transition --skip-download ` | ||
| --platform-url 'windows-x64:https://example.com/tool-windows.zip' | Out-Null | ||
| Test-Path 'transition.cmd' | Should -BeTrue | ||
|
|
||
| # Rewrite the same stub as unix-only, then regenerate through the same code path. | ||
| @' | ||
| #!/usr/bin/env -S mise tool-stub | ||
|
|
||
| [platforms.linux-x64] | ||
| url = "https://example.com/tool-linux.tar.gz" | ||
| '@ | Out-File -FilePath 'transition' -Encoding utf8NoBOM | ||
| mise generate tool-stub transition --skip-download ` | ||
| --platform-url 'linux-x64:https://example.com/tool-linux.tar.gz' | Out-Null | ||
|
|
||
| Test-Path 'transition.cmd' | Should -BeFalse | ||
| } | ||
|
|
||
| It 'leaves a launcher it did not write alone' { | ||
| mise generate tool-stub handwritten --skip-download ` | ||
| --platform-url 'linux-x64:https://example.com/tool-linux.tar.gz' | Out-Null | ||
| 'echo mine' | Out-File -FilePath 'handwritten.cmd' -Encoding utf8NoBOM | ||
|
|
||
| mise generate tool-stub handwritten --skip-download ` | ||
| --platform-url 'linux-x64:https://example.com/tool-linux.tar.gz' | Out-Null | ||
|
|
||
| Test-Path 'handwritten.cmd' | Should -BeTrue | ||
| (Get-Content 'handwritten.cmd' -Raw) | Should -BeLike '*echo mine*' | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.