<# .Synopsis Leiningen bootstrap. .Parameter Command The command to pass to leiningen. .Notes This is a very literal port of lein.bat to PowerShell. TODO: - Determine which (if any) environment variables are used from within Leiningen/Clojure and convert the rest to local- or script-scoped variables. - Probably should parse the version from the newest .jar filename, rather than hard-code it and search for the .jar file from it. - Further reduce/simplify/refactor away from batch-file idioms toward idiomatic PowerShell. .Link https://leiningen.org/ #> #require -version 3 [CmdletBinding(SupportsShouldProcess=$true)] Param( [Parameter(Position=0,ValueFromRemainingArguments=$true)][string[]]$Command = 'help' ) function Set-ParentLocation([string]$file) { for($dir = [IO.DirectoryInfo]"$PWD"; $dir.Parent; $dir = $dir.Parent) { if(Test-Path (Join-Path $dir.FullName $file) -PathType Leaf) { cd $dir.FullName; break } } } function Initialize-Environment { $env:LEIN_VERSION = '2.11.2' $env:SNAPSHOT = if($env:LEIN_VERSION -like '*-SNAPSHOT'){'YES'}else{'NO'} #TODO: Still needed? $env:ORIGINAL_PWD = $PWD -replace '\\$','\\' Set-ParentLocation project.clj if(!$env:LEIN_HOME) {$env:LEIN_HOME = "$env:USERPROFILE\.lein"} if(!$env:LEIN_JAR) {$env:LEIN_JAR = "$env:LEIN_HOME\self-installs\leiningen-$env:LEIN_VERSION-standalone.jar"} if($PSVersionTable.PSVersion.Major -gt 5) { if(!($([System.Net.WebProxy]::new()).IsBypassed('https://github.com/'))) { $proxy = $([System.Net.WebProxy]::new()).GetProxy('https://github.com/') Write-Verbose "Using proxy: $proxy" $Script:PSBoundParameters = @{ 'Invoke-WebRequest:Proxy' = $proxy 'Invoke-WebRequest:ProxyUseDefaultCredentials' = $true } } } else { if(!([Net.WebRequest]::DefaultWebProxy.IsBypassed('https://github.com/'))) { $proxy = [Net.WebRequest]::DefaultWebProxy.GetProxy('https://github.com/') Write-Verbose "Using proxy: $proxy" $Script:PSBoundParameters = @{ 'Invoke-WebRequest:Proxy' = $proxy 'Invoke-WebRequest:ProxyUseDefaultCredentials' = $true } } } } function Use-ClassPath([string]$Value) { $env:CLASSPATH = if(!(Test-Path .lein-classpath -PathType Leaf)) {$Value} else {"$(gc .lein-classpath |? {$_} |select -Last 1);$Value"} } function Initialize-Binary { if(!(Test-Path $env:LEIN_JAR -PathType Leaf)) {throw "$env:LEIN_JAR cannot be found. Try running 'lein self-install' or change the LEIN_JAR environment variable."} Use-ClassPath $env:LEIN_JAR } function Initialize-Source { $env:LEIN_ROOT = $PSScriptRoot $env:bootstrapfile = "$env:LEIN_ROOT\leiningen-core\.lein-bootstrap" Write-Verbose "LEIN_ROOT=$env:LEIN_ROOT" if($env:bootstrapfile -like '*;*') #TODO: Still important? {throw "bootstrap file ($env:bootstrapfile) should not contain semicolons!"} if(!(Test-Path $env:bootstrapfile -PathType Leaf)) {throw @' Leiningen is missing its dependencies. Run 'lein bootstrap' in the leiningen-core/ directory with a stable release. See CONTRIBUTING.md for details. '@} if((Get-Content $env:bootstrapfile -raw) -like '*"*') {throw "Double quotes detected inside bootstrap file $env:bootstrapfile!?"} $env:LEIN_LIBS = (Get-Content $env:bootstrapfile |% {$_ -split ';'} |% {"$_"}) -join ';' Write-Verbose "LEIN_LIBS=$env:LEIN_LIBS" Use-ClassPath "$env:LEIN_LIBS;$env:LEIN_ROOT\src;$env:LEIN_ROOT\resources" } function Install-Self { if(Test-Path $env:LEIN_JAR -PathType Leaf) {throw "$env:LEIN_JAR already exists. Delete and retry."} $jardir = ([IO.FileInfo]$env:LEIN_JAR).Directory.FullName if(!(Test-Path $jardir -PathType Container)) {mkdir $jardir |Out-Null} @{ # splatting Invoke-WebRequest due to long URI Uri = "https://github.com/technomancy/leiningen/releases/download/$env:LEIN_VERSION/leiningen-$env:LEIN_VERSION-standalone.jar" OutFile = $env:LEIN_JAR } |% {Write-Progress 'Install-Self' $_.Uri -CurrentOperation "Downloading to $env:LEIN_JAR" ; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest @_} Write-Progress 'Install-Self' -Completed } function Update-Self { $targetVersion = if($Command.Length -gt 1) {$Command[1]} else {'stable'} if(!$PSCmdlet.ShouldProcess($PSCommandPath,"upgrade to $targetVersion")) {throw 'Cancelled'} @{ # splatting Invoke-WebRequest due to long URI Uri = "https://github.com/technomancy/leiningen/raw/$targetVersion/bin/lein.cmd" OutFile = "$PSScriptRoot\lein.cmd.pending" } |% {Write-Progress 'Update-Self' $_.Uri -CurrentOperation "Downloading to $PSScriptRoot\lein.cmd.pending" ; Invoke-WebRequest @_} @{ # splatting Invoke-WebRequest due to long URI Uri = "https://github.com/technomancy/leiningen/raw/$targetVersion/bin/lein.ps1" OutFile = "$PSCommandPath.pending" } |% {Write-Progress 'Update-Self' $_.Uri -CurrentOperation "Downloading to $PSCommandPath.pending" -PercentComplete 50 ; Invoke-WebRequest @_} Write-Progress 'Update-Self' -Completed Move-Item "$PSScriptRoot\lein.cmd.pending" "$PSScriptRoot\lein.cmd" -force Move-Item "$PSCommandPath.pending" "$PSCommandPath" -force . "$PSCommandPath" self-install } function Invoke-Java { Write-Verbose "CLASSPATH=$env:CLASSPATH" $env:JAVA_CMD = if($env:JAVA_CMD){$env:JAVA_CMD -replace '\A"|"\Z',''}else{'java'} $env:LEIN_JAVA_CMD = if($env:LEIN_JAVA_CMD){$env:LEIN_JAVA_CMD -replace '\A"|"\Z',''}else{$env:JAVA_CMD} if(!$env:JVM_OPTS){$env:JVM_OPTS = $env:JAVA_OPTS} $JavaArgs = @( '-client',$env:LEIN_JVM_OPTS, '-Dfile.encoding=UTF-8', "`"-Dclojure.compile.path=$PWD/target/classes`"", #TODO: Add this line only when we're initializing from source "`"-Dleiningen.original.pwd=$env:ORIGINAL_PWD`"", '-cp',$env:CLASSPATH, 'clojure.main', '-m','leiningen.core.main' ) &$env:LEIN_JAVA_CMD @JavaArgs @Command } function Invoke-Leiningen { Initialize-Environment switch($Command[0]) { self-install {Install-Self} upgrade {Update-Self } downgrade {Update-Self } default { if(Test-Path "$PSCommandPath\..\src\leiningen\version.clj" -PathType Leaf) {Initialize-Source} else {Initialize-Binary} Invoke-Java } } } Invoke-Leiningen