New-ShellWrappers.psm1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
<# .SYNOPSIS Creates shell (PowerShell, Bash, CMD) scripts to launch the given Python/PowerShell file without typing an extension. .DESCRIPTION For Python files, creates: .ps1, used in: Windows PowerShell 5 (built-in to Windows 10) Windows PowerShell 7 Linux Bash Linux PowerShell 7 For Python and PowerShell files, creates: .bat, used in: Windows Command Shell (CMD) Windows PowerShell 5 (built-in to Windows 10) Windows PowerShell 7 no extension, used in: Linux Bash Linux PowerShell 7 .PARAMETER FileToWrap The PowerShell (.ps1) or Python (.py) file that will be run by the created shell wrappers. .INPUTS None. You cannot pipe objects to New-ShellWrappers .OUTPUTS Creates .ps1 (if FileToWrap is .py), .bat, extension-less shell wrappers in the same location as given FileToWrap. .LINK https://www.powershellgallery.com/packages/New-ShellWrappers .LINK https://github.com/lenihan/New-ShellWrappers #> function New-ShellWrappers { Param([Parameter(Mandatory=$true)][ValidateScript({Test-Path $PSItem})]$FileToWrap) $version = "1.0.0" # wrapper generater version $FileToWrap = Convert-Path $FileToWrap # convert to full path $gi = Get-Item $FileToWrap $dir = $gi.DirectoryName $base = $gi.BaseName $ext = $gi.Extension $crlf = "`r`n" # Windows line ending $lf = "`n" # Linux line ending $pwshContents = '#!/bin/pwsh-preview' + $crlf $pwshContents += '# DO NOT EDIT' + $crlf $pwshContents += '# Autogenerated by $PSCommandPath' + $crlf $pwshContents += '# Version: $version' + $crlf $pwshContents += '`$gi = Get-Item `$PSCommandPath' + $crlf $pwshContents += '`$dir = `$gi.DirectoryName' + $crlf $pwshContents += '`$base = `$gi.BaseName' + $crlf $pwshContents += '`$script = Join-Path `$dir "`$base$ext"' + $crlf $pwshContents += '$app `$script `$args' $cmdContents = '@REM DO NOT EDIT' + $crlf $cmdContents += '@REM Autogenerated by $PSCommandPath' + $crlf $cmdContents += '@REM Version: $version' + $crlf $cmdContents += '@$app %~dpn0$ext %*' $bashContents = '#!/usr/bin/env bash' + $lf $bashContents += '# DO NOT EDIT' + $lf $bashContents += '# Autogenerated by $PSCommandPath' + $lf $bashContents += '# Version: $version' + $lf $bashContents += 'filename=`$(basename -- "`$0")' + $lf $bashContents += 'base=`${filename%.*}' + $lf $bashContents += 'dir="`$( cd "`$(dirname "`$0")" ; pwd -P )"' + $lf $bashContents += '$app "`$dir/`$base$ext" $@' $wrappers = @{ '.py' = @{ pwsh = @{ext = '.ps1'; contents = $pwshContents; app = 'python'} cmd = @{ext = '.bat'; contents = $cmdContents; app = 'python'} bash = @{ext = ''; contents = $bashContents; app = 'python'} } '.ps1' = @{ cmd = @{ext = '.bat'; contents = $cmdContents; app = 'pwsh-preview'} bash = @{ext = ''; contents = $bashContents; app = 'pwsh-preview'} } } if (!$wrappers[$ext]) { Write-Host "Do not know how to create wrapper for given file extension '$ext'" -ForegroundColor Yellow } else { foreach ($shell in $wrappers[$ext].keys) { $wrapperContents = $wrappers[$ext][$shell].contents $wrapperExt = $wrappers[$ext][$shell].ext $app = $wrappers[$ext][$shell].app $value = $ExecutionContext.InvokeCommand.ExpandString($wrapperContents) $path = Join-Path $dir "$base$wrapperExt" Write-Host "# Creating $shell wrapper $version to run '$app $base$ext' - $path" Set-Content -Path $path -Value $value } } Write-Host "# Done" -ForegroundColor Green <# # Copy/paste the following into PowerShell to generate test files. # # Use test files to validate wrappers work. Things to check... # Verify arguments are passed correctly (testPython.ps1 a b c) # Verify generated .ps1 works on... # Windows PowerShell 5 # Windows PowerShell 7 # Linux Bash # Linux PowerShell 7 # Verify generated .bat works on... # Windows CMD # Windows PowerShell 5 # Windows PowerShell 7 # Verify generated extension-less file works on... # Linux Bash # Linux PowerShell 7 # For Linux, verify CentOS7 and Ubuntu $testPwshContents = @' #!/usr/bin/env pwsh-preview "Greetings from PowerShell" "Args..." foreach ($a in $args) {$a} '@ Set-Content -Path testPwsh.ps1 -Value $testPwshContents $testPythonContents = @' import sys print("Greetings from Python") print("Args...") for a in sys.argv: print(a) '@ Set-Content -Path testPython.py -Value $testPythonContents #> } Export-ModuleMember -Function New-ShellWrappers |