From 5452c71585c2c829c3c01666f203f15b389dad8b Mon Sep 17 00:00:00 2001 From: "ASP.NET Push Bot" Date: Mon, 27 Jul 2015 15:49:06 -0700 Subject: [PATCH] :arrow_up: dnvm.ps1, dnvm.cmd, dnvm.sh Source: AspNet/kvm@bb181df257710495989864be6696fdb658598c1f --- dnvm.ps1 | 398 +++++++++++++++++++++++++++++++++++++++++-------------- dnvm.sh | 145 ++++++++++++++------ 2 files changed, 409 insertions(+), 134 deletions(-) diff --git a/dnvm.ps1 b/dnvm.ps1 index 60c78ff951..79801e863c 100644 --- a/dnvm.ps1 +++ b/dnvm.ps1 @@ -67,7 +67,7 @@ function _WriteOut { ### Constants $ProductVersion="1.0.0" -$BuildVersion="beta6-10397" +$BuildVersion="beta7-10399" $Authors="Microsoft Open Technologies, Inc." # If the Version hasn't been replaced... @@ -94,6 +94,7 @@ Set-Variable -Option Constant "CommandPrefix" "dnvm-" Set-Variable -Option Constant "DefaultArchitecture" "x86" Set-Variable -Option Constant "DefaultRuntime" "clr" Set-Variable -Option Constant "AliasExtension" ".txt" +Set-Variable -Option Constant "DefaultOperatingSystem" "win" # These are intentionally using "%" syntax. The environment variables are expanded whenever the value is used. Set-Variable -Option Constant "OldUserHomes" @("%USERPROFILE%\.kre", "%USERPROFILE%\.k") @@ -134,6 +135,8 @@ if(!$ColorScheme) { "Help_Executable"=[ConsoleColor]::DarkYellow "Feed_Name"=[ConsoleColor]::Cyan "Warning" = [ConsoleColor]::Yellow + "Error" = [ConsoleColor]::Red + "ActiveRuntime" = [ConsoleColor]::Cyan } } @@ -254,22 +257,62 @@ function Safe-Filecopy { } } -function GetArch($Architecture, $FallBackArch = $DefaultArchitecture) { - if(![String]::IsNullOrEmpty($Architecture)) { - $Architecture - } elseif($CompatArch) { - $CompatArch - } else { - $FallBackArch - } +$OSRuntimeDefaults = @{ + "win"="clr"; + "linux"="mono"; + "darwin"="mono"; } -function GetRuntime($Runtime) { - if(![String]::IsNullOrEmpty($Runtime)) { - $Runtime - } else { - $DefaultRuntime +$RuntimeBitnessDefaults = @{ + "clr"="x86"; + "coreclr"="x64"; +} + +function GetRuntimeInfo($Architecture, $Runtime, $OS, $Version) { + $runtimeInfo = @{ + "Architecture"="$Architecture"; + "Runtime"="$Runtime"; + "OS"="$OS"; + "Version"="$Version"; } + + if([String]::IsNullOrEmpty($runtimeInfo.OS)) { + if($runtimeInfo.Runtime -eq "mono"){ + #If OS is empty and you are asking for mono, i.e `dnvm install latest -os mono` then we don't know what OS to pick. It could be Linux or Darwin. + #we could just arbitrarily pick one but it will probably be wrong as often as not. + #If Mono can run on Windows then this error doesn't make sense anymore. + throw "Unable to determine an operating system for a $($runtimeInfo.Runtime) runtime. You must specify which OS to use with the OS parameter." + } + $runtimeInfo.OS = $DefaultOperatingSystem + } + + if($runtimeInfo.OS -eq "osx") { + $runtimeInfo.OS = "darwin" + } + + if([String]::IsNullOrEmpty($runtimeInfo.Runtime)) { + $runtimeInfo.Runtime = $OSRuntimeDefaults.Get_Item($runtimeInfo.OS) + } + + if([String]::IsNullOrEmpty($runtimeInfo.Architecture)) { + $runtimeInfo.Architecture = $RuntimeBitnessDefaults.Get_Item($RuntimeInfo.Runtime) + } + + $runtimeObject = New-Object PSObject -Property $runtimeInfo + + $runtimeObject | Add-Member -MemberType ScriptProperty -Name RuntimeId -Value { + if($this.Runtime -eq "mono") { + "$RuntimePackageName-$($this.Runtime)".ToLowerInvariant() + } else { + "$RuntimePackageName-$($this.Runtime)-$($this.OS)-$($this.Architecture)".ToLowerInvariant() + } + } + + $runtimeObject | Add-Member -MemberType ScriptProperty -Name RuntimeName -Value { + "$($this.RuntimeId).$($this.Version)" + } + + $runtimeObject } function Write-Usage { @@ -330,32 +373,24 @@ function IsOnPath { $env:Path.Split(';') -icontains $dir } -function Get-RuntimeId( - [Parameter()][string]$Architecture, - [Parameter()][string]$Runtime) { - - $Architecture = GetArch $Architecture - $Runtime = GetRuntime $Runtime - - "$RuntimePackageName-$Runtime-win-$Architecture".ToLowerInvariant() -} - -function Get-RuntimeName( +function Get-RuntimeAliasOrRuntimeInfo( [Parameter(Mandatory=$true)][string]$Version, [Parameter()][string]$Architecture, - [Parameter()][string]$Runtime) { + [Parameter()][string]$Runtime, + [Parameter()][string]$OS) { $aliasPath = Join-Path $AliasesDir "$Version$AliasExtension" if(Test-Path $aliasPath) { $BaseName = Get-Content $aliasPath - $Architecture = GetArch $Architecture (Get-PackageArch $BaseName) - $Runtime = GetRuntime $Runtime (Get-PackageArch $BaseName) + $Architecture = Get-PackageArch $BaseName + $Runtime = Get-PackageRuntime $BaseName $Version = Get-PackageVersion $BaseName + $OS = Get-PackageOS $BaseName } - "$(Get-RuntimeId $Architecture $Runtime).$Version" + GetRuntimeInfo $Architecture $Runtime $OS $Version } filter List-Parts { @@ -379,6 +414,12 @@ filter List-Parts { $parts1 = $_.Name.Split('.', 2) $parts2 = $parts1[0].Split('-', 4) + + if($parts1[0] -eq "$RuntimePackageName-mono") { + $parts2 += "linux/darwin" + $parts2 += "x86/x64" + } + return New-Object PSObject -Property @{ Active = $active Version = $parts1[1] @@ -411,14 +452,16 @@ function Write-Alias { [Parameter(Mandatory=$true)][string]$Name, [Parameter(Mandatory=$true)][string]$Version, [Parameter(Mandatory=$false)][string]$Architecture, - [Parameter(Mandatory=$false)][string]$Runtime) + [Parameter(Mandatory=$false)][string]$Runtime, + [Parameter(Mandatory=$false)][string]$OS) # If the first character is non-numeric, it's a full runtime name if(![Char]::IsDigit($Version[0])) { - $runtimeFullName = $Version + $runtimeInfo = GetRuntimeInfo $(Get-PackageArch $Version) $(Get-PackageRuntime $Version) $(Get-PackageOS $Version) $(Get-PackageVersion $Version) } else { - $runtimeFullName = Get-RuntimeName $Version $Architecture $Runtime + $runtimeInfo = GetRuntimeInfo $Architecture $Runtime $OS $Version } + $aliasFilePath = Join-Path $AliasesDir "$Name.txt" $action = if (Test-Path $aliasFilePath) { "Updating" } else { "Setting" } @@ -426,8 +469,8 @@ function Write-Alias { _WriteDebug "Creating alias directory: $AliasesDir" New-Item -Type Directory $AliasesDir | Out-Null } - _WriteOut "$action alias '$Name' to '$runtimeFullName'" - $runtimeFullName | Out-File $aliasFilePath ascii + _WriteOut "$action alias '$Name' to '$($runtimeInfo.RuntimeName)'" + $runtimeInfo.RuntimeName | Out-File $aliasFilePath ascii } function Delete-Alias { @@ -468,16 +511,15 @@ param( function Find-Latest { param( - [string]$runtime = "", - [string]$architecture = "", + $runtimeInfo, [Parameter(Mandatory=$true)] [string]$Feed, [string]$Proxy ) _WriteOut "Determining latest version" - - $RuntimeId = Get-RuntimeId -Architecture:"$architecture" -Runtime:"$runtime" + $RuntimeId = $runtimeInfo.RuntimeId + _WriteDebug "Latest RuntimeId: $RuntimeId" $url = "$Feed/GetUpdates()?packageIds=%27$RuntimeId%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false" # NOTE: DO NOT use Invoke-WebRequest. It requires PowerShell 4.0! @@ -522,18 +564,23 @@ function Get-PackageArch() { return $runtimeFullName -replace "$RuntimePackageName-[^-]*-[^-]*-([^.]*).*", '$1' } +function Get-PackageOS() { + param( + [string] $runtimeFullName + ) + $runtimeFullName -replace "$RuntimePackageName-[^-]*-([^-]*)-[^.]*.*", '$1' +} + function Download-Package( - [string]$Version, - [string]$Architecture, - [string]$Runtime, + $runtimeInfo, [string]$DestinationFile, [Parameter(Mandatory=$true)] [string]$Feed, [string]$Proxy) { - $url = "$Feed/package/" + (Get-RuntimeId $Architecture $Runtime) + "/" + $Version - _WriteOut "Downloading $runtimeFullName from $feed" + $url = "$Feed/package/" + ($runtimeInfo.RuntimeId) + "/" + $runtimeInfo.Version + _WriteOut "Downloading $($runtimeInfo.RuntimeName) from $feed" $wc = New-Object System.Net.WebClient try { Apply-Proxy $wc -Proxy:$Proxy @@ -736,8 +783,19 @@ function dnvm-update-self { _WriteOut "Updating $CommandName from $DNVMUpgradeUrl" $wc = New-Object System.Net.WebClient Apply-Proxy $wc -Proxy:$Proxy + $dnvmFile = Join-Path $PSScriptRoot "dnvm.ps1" - $wc.DownloadFile($DNVMUpgradeUrl, $dnvmFile) + $tempDnvmFile = Join-Path $PSScriptRoot "dnvm.ps1" "temp" + $backupFilePath = Join-Path $PSSCriptRoot "dnvm.ps1.bak" + + $wc.DownloadFile($DNVMUpgradeUrl, $tempDnvmFile) + + if(Test-Path $backupFilePath) { + Remove-Item $backupFilePath -Force + } + + Rename-Item $dnvmFile $backupFilePath + Rename-Item $tempDnvmFile $dnvmFile } <# @@ -861,17 +919,36 @@ function dnvm-help { } } +filter ColorActive { + param([string] $color) + $lines = $_.Split("`n") + foreach($line in $lines) { + if($line.Contains("*")){ + _WriteOut -ForegroundColor $ColorScheme.ActiveRuntime $line + } else { + _WriteOut $line + } + } +} + <# .SYNOPSIS Lists available runtimes +.PARAMETER Detailed + Display more detailed information on each runtime .PARAMETER PassThru Set this switch to return unformatted powershell objects for use in scripting #> function dnvm-list { param( - [Parameter(Mandatory=$false)][switch]$PassThru) + [Parameter(Mandatory=$false)][switch]$PassThru, + [Parameter(Mandatory=$false)][switch]$Detailed) $aliases = Get-RuntimeAlias + if(-not $PassThru) { + Check-Runtimes + } + $items = @() $RuntimeHomes | ForEach-Object { _WriteDebug "Scanning $_ for runtimes..." @@ -883,9 +960,20 @@ function dnvm-list { if($PassThru) { $items } else { - $items | - Sort-Object Version, Runtime, Architecture, Alias | - Format-Table -AutoSize -Property @{name="Active";expression={if($_.Active) { "*" } else { "" }};alignment="center"}, "Version", "Runtime", "Architecture", "Location", "Alias" + if($items) { + #TODO: Probably a better way to do this. + if($Detailed) { + $items | + Sort-Object Version, Runtime, Architecture, OperatingSystem, Alias | + Format-Table -AutoSize -Property @{name="Active";expression={if($_.Active) { "*" } else { "" }};alignment="center"}, "Version", "Runtime", "Architecture", "OperatingSystem", "Alias", "Location" | Out-String| ColorActive + } else { + $items | + Sort-Object Version, Runtime, Architecture, OperatingSystem, Alias | + Format-Table -AutoSize -Property @{name="Active";expression={if($_.Active) { "*" } else { "" }};alignment="center"}, "Version", "Runtime", "Architecture", "OperatingSystem", "Alias" | Out-String | ColorActive + } + } else { + _WriteOut "No runtimes installed. You can run `dnvm install latest` or `dnvm upgrade` to install a runtime." + } } } @@ -900,6 +988,8 @@ function dnvm-list { The architecture of the runtime to assign to this alias .PARAMETER Runtime The flavor of the runtime to assign to this alias +.PARAMETER OS + The operating system that the runtime targets .PARAMETER Delete Set this switch to delete the alias with the specified name .DESCRIPTION @@ -909,14 +999,20 @@ function dnvm-list { (defaults to 'x86') and (defaults to 'clr'). Finally, if the '-d' switch is provided, the alias is deleted, if it exists. + + NOTE: You cannot create an alias for a non-windows runtime. The intended use case for + an alias to help make it easier to switch the runtime, and you cannot use a non-windows + runtime on a windows machine. #> function dnvm-alias { param( [Alias("d")] [switch]$Delete, + [Parameter(Position=0)] [string]$Name, + [Parameter(Position=1)] [string]$Version, [Alias("arch")] @@ -924,11 +1020,23 @@ function dnvm-alias { [string]$Architecture = "", [Alias("r")] - [ValidateSet("", "clr", "coreclr")] - [string]$Runtime = "") + [ValidateSet("", "clr","coreclr", "mono")] + [Parameter(ParameterSetName="Write")] + [string]$Runtime = "", + + [ValidateSet("win", "osx", "darwin", "linux")] + [Parameter(Mandatory=$false,ParameterSetName="Write")] + [string]$OS = "") + + if($Name -like "help" -or $Name -like "/?") { + #It is unlikely that the user is trying to read an alias called help, so lets just help them out by displaying help text. + #If people need an alias called help or one that contains a `?` then we can change this to a prompt. + dnvm help alias + return + } if($Version) { - Write-Alias $Name $Version -Architecture $Architecture -Runtime $Runtime + Write-Alias $Name $Version -Architecture $Architecture -Runtime $Runtime -OS:$OS } elseif ($Delete) { Delete-Alias $Name } else { @@ -958,6 +1066,8 @@ function dnvm-unalias { The processor architecture of the runtime to install (default: x86) .PARAMETER Runtime The runtime flavor to install (default: clr) +.PARAMETER OS + The operating system that the runtime targets (default: win) .PARAMETER Force Overwrite an existing runtime if it already exists .PARAMETER Proxy @@ -984,6 +1094,10 @@ function dnvm-upgrade { [ValidateSet("", "clr", "coreclr")] [Parameter(Mandatory=$false)] [string]$Runtime = "", + + [ValidateSet("", "win", "osx", "darwin", "linux")] + [Parameter(Mandatory=$false)] + [string]$OS = "", [Alias("f")] [Parameter(Mandatory=$false)] @@ -1001,7 +1115,15 @@ function dnvm-upgrade { [Parameter(Mandatory=$false)] [switch]$Unstable) - dnvm-install "latest" -Alias:$Alias -Architecture:$Architecture -Runtime:$Runtime -Force:$Force -Proxy:$Proxy -NoNative:$NoNative -Ngen:$Ngen -Unstable:$Unstable -Persistent:$true + if($OS -ne "win") { + #We could remove OS as an option from upgrade, but I want to take this opporunty to educate users about the difference between install and upgrade + #It's possible we should just do install here instead. + _WriteOut -ForegroundColor $ColorScheme.Error "You cannot upgrade to a non-windows runtime. Upgrade will download the latest version of the $RuntimeShortFriendlyName and also set it as your machines default. You cannot set the default $RuntimeShortFriendlyName to a non-windows version because you cannot use it to run an application. If you want to install a non-windows $RuntimeShortFriendlyName to package with your application then use 'dnvm install latest -OS:$OS' instead. Install will download the package but not set it as your default." + $Script:ExitCode = $ExitCodes.OtherError + return + } + + dnvm-install "latest" -Alias:$Alias -Architecture:$Architecture -Runtime:$Runtime -OS:$OS -Force:$Force -Proxy:$Proxy -NoNative:$NoNative -Ngen:$Ngen -Unstable:$Unstable -Persistent:$true } <# @@ -1015,6 +1137,8 @@ function dnvm-upgrade { The processor architecture of the runtime to install (default: x86) .PARAMETER Runtime The runtime flavor to install (default: clr) +.PARAMETER OS + The operating system that the runtime targets (default: win) .PARAMETER Alias Set alias to the installed runtime .PARAMETER Force @@ -1043,10 +1167,14 @@ function dnvm-install { [string]$Architecture = "", [Alias("r")] - [ValidateSet("", "clr", "coreclr")] + [ValidateSet("", "clr","coreclr","mono")] [Parameter(Mandatory=$false)] [string]$Runtime = "", + [ValidateSet("", "win", "osx", "darwin", "linux")] + [Parameter(Mandatory=$false)] + [string]$OS = "", + [Alias("a")] [Parameter(Mandatory=$false)] [string]$Alias, @@ -1085,8 +1213,8 @@ function dnvm-install { $selectedFeed = $DefaultFeed } else { _WriteOut -ForegroundColor $ColorScheme.Warning "Default stable feed ($DefaultFeed) is being overridden by the value of the $DefaultFeedKey environment variable ($ActiveFeed)" - } - } + } + } if(!$VersionNuPkgOrAlias) { _WriteOut "A version, nupkg path, or the string 'latest' must be provided." @@ -1095,11 +1223,6 @@ function dnvm-install { return } - if ($VersionNuPkgOrAlias -eq "latest") { - Write-Progress -Status "Determining Latest Runtime" -Activity "Installing runtime" -Id 1 - $VersionNuPkgOrAlias = Find-Latest $Runtime $Architecture -Feed:$selectedFeed - } - $IsNuPkg = $VersionNuPkgOrAlias.EndsWith(".nupkg") if ($IsNuPkg) { @@ -1110,18 +1233,52 @@ function dnvm-install { $runtimeFullName = [System.IO.Path]::GetFileNameWithoutExtension($VersionNuPkgOrAlias) $Architecture = Get-PackageArch $runtimeFullName $Runtime = Get-PackageRuntime $runtimeFullName + $OS = Get-PackageOS $runtimeFullName + $Version = Get-PackageVersion $VersionNuPkgOrAlias } else { - $runtimeFullName = Get-RuntimeName $VersionNuPkgOrAlias -Architecture:$Architecture -Runtime:$Runtime + $aliasPath = Join-Path $AliasesDir "$VersionNuPkgOrAlias$AliasExtension" + if(Test-Path $aliasPath) { + $BaseName = Get-Content $aliasPath + #Check empty checks let us override a given alias property when installing the same again. e.g. `dnvm install default -x64` + if([String]::IsNullOrEmpty($Architecture)) { + $Architecture = Get-PackageArch $BaseName + } + + if([String]::IsNullOrEmpty($Runtime)) { + $Runtime = Get-PackageRuntime $BaseName + } + + if([String]::IsNullOrEmpty($Version)) { + $Version = Get-PackageVersion $BaseName + } + + if([String]::IsNullOrEmpty($Architecture)) { + $OS = Get-PackageOS $BaseName + } + } } - $PackageVersion = Get-PackageVersion $runtimeFullName - - _WriteDebug "Preparing to install runtime '$runtimeFullName'" - _WriteDebug "Architecture: $Architecture" - _WriteDebug "Runtime: $Runtime" - _WriteDebug "Version: $PackageVersion" + $runtimeInfo = GetRuntimeInfo $Architecture $Runtime $OS $VersionNupkgOrAlias - $RuntimeFolder = Join-Path $RuntimesDir $runtimeFullName + if ($VersionNuPkgOrAlias -eq "latest") { + Write-Progress -Activity "Installing runtime" -Status "Determining latest runtime" -Id 1 + $Version = Find-Latest -runtimeInfo:$runtimeInfo -Feed:$selectedFeed + } + + #If the version is still empty at this point then VersionOrNupkgOrAlias is an actual version. + if([String]::IsNullOrEmpty($Version)) { + $Version = $VersionNuPkgOrAlias + } + + $runtimeInfo.Version = $Version + + _WriteDebug "Preparing to install runtime '$($runtimeInfo.RuntimeName)'" + _WriteDebug "Architecture: $($runtimeInfo.Architecture)" + _WriteDebug "Runtime: $($runtimeInfo.Runtime)" + _WriteDebug "Version: $($runtimeInfo.Version)" + _WriteDebug "OS: $($runtimeInfo.OS)" + + $RuntimeFolder = Join-Path $RuntimesDir $($runtimeInfo.RuntimeName) _WriteDebug "Destination: $RuntimeFolder" if((Test-Path $RuntimeFolder) -and $Force) { @@ -1130,12 +1287,17 @@ function dnvm-install { } if(Test-Path $RuntimeFolder) { - _WriteOut "'$runtimeFullName' is already installed." - dnvm-use $PackageVersion -Architecture:$Architecture -Runtime:$Runtime -Persistent:$Persistent + _WriteOut "'$($runtimeInfo.RuntimeName)' is already installed." + if($runtimeInfo.OS -eq "win") { + dnvm-use $runtimeInfo.Version -Architecture:$runtimeInfo.Architecture -Runtime:$runtimeInfo.Runtime -Persistent:$Persistent -OS:$runtimeInfo.OS + } } else { - $Architecture = GetArch $Architecture - $Runtime = GetRuntime $Runtime + + $Architecture = $runtimeInfo.Architecture + $Runtime = $runtimeInfo.Runtime + $OS = $runtimeInfo.OS + $TempFolder = Join-Path $RuntimesDir "temp" $UnpackFolder = Join-Path $TempFolder $runtimeFullName $DownloadFile = Join-Path $UnpackFolder "$runtimeFullName.nupkg" @@ -1153,9 +1315,9 @@ function dnvm-install { } else { # Download the package Write-Progress -Activity "Installing runtime" -Status "Downloading runtime" -Id 1 - _WriteDebug "Downloading version $VersionNuPkgOrAlias to $DownloadFile" + _WriteDebug "Downloading version $($runtimeInfo.Version) to $DownloadFile" - Download-Package $PackageVersion $Architecture $Runtime $DownloadFile -Proxy:$Proxy -Feed:$selectedFeed + Download-Package -RuntimeInfo:$runtimeInfo -DestinationFile:$DownloadFile -Proxy:$Proxy -Feed:$selectedFeed } Write-Progress -Activity "Installing runtime" -Status "Unpacking runtime" -Id 1 @@ -1163,7 +1325,7 @@ function dnvm-install { if(Test-Path $RuntimeFolder) { # Ensure the runtime hasn't been installed in the time it took to download the package. - _WriteOut "'$runtimeFullName' is already installed." + _WriteOut "'$($runtimeInfo.RuntimeName)' is already installed." } else { _WriteOut "Installing to $RuntimeFolder" @@ -1178,31 +1340,33 @@ function dnvm-install { } } #If there is nothing left in the temp folder remove it. There could be other installs happening at the same time as this. - if(-Not(Test-Path $(Join-Path $TempFolder "*"))) { + if(Test-Path $(Join-Path $TempFolder "*")) { Remove-Item $TempFolder -Recurse } } - dnvm-use $PackageVersion -Architecture:$Architecture -Runtime:$Runtime -Persistent:$Persistent - - if ($Runtime -eq "clr") { + if($runtimeInfo.OS -eq "win") { + dnvm-use $runtimeInfo.Version -Architecture:$runtimeInfo.Architecture -Runtime:$runtimeInfo.Runtime -Persistent:$Persistent -OS:$runtimeInfo.OS + } + + if ($runtimeInfo.Runtime -eq "clr") { if (-not $NoNative) { if ((Is-Elevated) -or $Ngen) { - $runtimeBin = Get-RuntimePath $runtimeFullName + $runtimeBin = Get-RuntimePath $runtimeInfo.RuntimeName Write-Progress -Activity "Installing runtime" -Status "Generating runtime native images" -Id 1 - Ngen-Library $runtimeBin $Architecture + Ngen-Library $runtimeBin $runtimeInfo.Architecture } else { _WriteOut "Native image generation (ngen) is skipped. Include -Ngen switch to turn on native image generation to improve application startup time." } } } - elseif ($Runtime -eq "coreclr") { - if ($NoNative) { + elseif ($runtimeInfo.Runtime -eq "coreclr") { + if ($NoNative -or $runtimeInfo.OS -ne "win") { _WriteOut "Skipping native image compilation." } else { - _WriteOut "Compiling native images for $runtimeFullName to improve startup performance..." + _WriteOut "Compiling native images for $($runtimeInfo.RuntimeName) to improve startup performance..." Write-Progress -Activity "Installing runtime" -Status "Generating runtime native images" -Id 1 if(Get-Command $CrossGenCommand -ErrorAction SilentlyContinue) { @@ -1221,13 +1385,17 @@ function dnvm-install { } } else { - _WriteOut "Unexpected platform: $Runtime. No optimization would be performed on the package installed." + _WriteOut "Unexpected platform: $($runtimeInfo.Runtime). No optimization would be performed on the package installed." } } if($Alias) { - _WriteDebug "Aliasing installed runtime to '$Alias'" - dnvm-alias $Alias $PackageVersion -Architecture:$Architecture -Runtime:$Runtime + if($runtimeInfo.OS -eq "win") { + _WriteDebug "Aliasing installed runtime to '$Alias'" + dnvm-alias $Alias $runtimeInfo.Version -Architecture:$RuntimeInfo.Architecture -Runtime:$RuntimeInfo.Runtime -OS:$RuntimeInfo.OS + } else { + _WriteOut "Unable to set an alias for a non-windows runtime. Installing non-windows runtimes on Windows are meant only for publishing, not running." + } } Write-Progress -Status "Done" -Activity "Install complete" -Id 1 -Complete @@ -1243,6 +1411,8 @@ function dnvm-install { The processor architecture of the runtime to place on the PATH (default: x86, or whatever the alias specifies in the case of use-ing an alias) .PARAMETER Runtime The runtime flavor of the runtime to place on the PATH (default: clr, or whatever the alias specifies in the case of use-ing an alias) +.PARAMETER OS + The operating system that the runtime targets (default: win) .PARAMETER Persistent Make the change persistent across all processes run by the current user #> @@ -1260,6 +1430,10 @@ function dnvm-use { [ValidateSet("", "clr", "coreclr")] [Parameter(Mandatory=$false)] [string]$Runtime = "", + + [ValidateSet("", "win", "osx", "darwin", "linux")] + [Parameter(Mandatory=$false)] + [string]$OS = "", [Alias("p")] [Parameter(Mandatory=$false)] @@ -1277,8 +1451,9 @@ function dnvm-use { } return; } - - $runtimeFullName = Get-RuntimeName $VersionOrAlias $Architecture $Runtime + + $runtimeInfo = Get-RuntimeAliasOrRuntimeInfo -Version:$VersionOrAlias -Architecture:$Architecture -Runtime:$Runtime -OS:$OS + $runtimeFullName = $runtimeInfo.RuntimeName $runtimeBin = Get-RuntimePath $runtimeFullName if ($runtimeBin -eq $null) { throw "Cannot find $runtimeFullName, do you need to run '$CommandName install $versionOrAlias'?" @@ -1321,10 +1496,11 @@ function dnvm-run { [Parameter(Mandatory=$false, Position=1, ValueFromRemainingArguments=$true)] [object[]]$DnxArguments) - $runtimeFullName = Get-RuntimeName $VersionOrAlias $Architecture $Runtime - $runtimeBin = Get-RuntimePath $runtimeFullName + $runtimeInfo = Get-RuntimeAliasOrRuntimeInfo -Version:$VersionOrAlias + + $runtimeBin = Get-RuntimePath $runtimeInfo.RuntimeName if ($runtimeBin -eq $null) { - throw "Cannot find $runtimeFullName, do you need to run '$CommandName install $versionOrAlias'?" + throw "Cannot find $($runtimeInfo.Name), do you need to run '$CommandName install $versionOrAlias'?" } $dnxExe = Join-Path $runtimeBin "dnx.exe" if(!(Test-Path $dnxExe)) { @@ -1361,10 +1537,11 @@ function dnvm-exec { [Parameter(Mandatory=$false, Position=2, ValueFromRemainingArguments=$true)] [object[]]$Arguments) - $runtimeFullName = Get-RuntimeName $VersionOrAlias $Architecture $Runtime - $runtimeBin = Get-RuntimePath $runtimeFullName + $runtimeInfo = Get-RuntimeAliasOrRuntimeInfo -Version:$VersionOrAlias + $runtimeBin = Get-RuntimePath $runtimeInfo.RuntimeName + if ($runtimeBin -eq $null) { - throw "Cannot find $runtimeFullName, do you need to run '$CommandName install $versionOrAlias'?" + throw "Cannot find $($runtimeInfo.RuntimeName), do you need to run '$CommandName install $versionOrAlias'?" } $oldPath = $env:PATH @@ -1435,6 +1612,35 @@ function dnvm-setup { } } +function Check-Runtimes(){ + $runtimesInstall = $false; + foreach($runtimeHomeDir in $RuntimeHomes) { + if (Test-Path "$runtimeHomeDir\runtimes") { + if(Test-Path "$runtimeHomeDir\runtimes\$RuntimePackageName-*"){ + $runtimesInstall = $true; + break; + } + } + } + + if (-not $runtimesInstall){ + $title = "Getting started" + $message = "It looks like you don't have any runtimes installed. Do you want us to install a $RuntimeShortFriendlyName to get you started?" + + $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Install the latest runtime for you" + + $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Do not install the latest runtime and continue" + + $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) + + $result = $host.ui.PromptForChoice($title, $message, $options, 0) + + if($result -eq 0){ + dnvm-upgrade + } + } +} + ### The main "entry point" # Check for old DNX_HOME values @@ -1475,7 +1681,7 @@ if($cmdargs -icontains "-amd64") { $cmdargs = @($cmdargs | Where-Object { @("-amd64", "-x86", "-x64") -notcontains $_ }) if(!$cmd) { - _WriteOut "You must specify a command!" + Check-Runtimes $cmd = "help" $Script:ExitCode = $ExitCodes.InvalidArguments } diff --git a/dnvm.sh b/dnvm.sh index a092d197db..56f06abfea 100644 --- a/dnvm.sh +++ b/dnvm.sh @@ -2,7 +2,7 @@ # Source this file from your .bash-profile or script to use # "Constants" -_DNVM_BUILDNUMBER="beta6-10397" +_DNVM_BUILDNUMBER="beta7-10399" _DNVM_AUTHORS="Microsoft Open Technologies, Inc." _DNVM_RUNTIME_PACKAGE_NAME="dnx" _DNVM_RUNTIME_FRIENDLY_NAME=".NET Execution Environment" @@ -67,13 +67,37 @@ __dnvm_current_os() fi } +__dnvm_os_runtime_defaults() +{ + local os=$1 + + if [[ $os == "win" ]]; then + echo "clr" + elif [[ $os == "linux" ]]; then + echo "mono" + elif [[ $os == "darwin" ]]; then + echo "mono" + else + echo "unknown os" + fi +} + +__dnvm_runtime_bitness_defaults() +{ + local runtime=$1 + if [[ $runtime == "clr" ]]; then + echo "x86" + elif [[ $runtime == "coreclr" ]]; then + echo "x64" + else + echo "unknown runtime" + fi +} + __dnvm_find_latest() { local platform=$1 local arch=$2 - - if [ -z $platform ]; then - local platform="mono" - fi + local os=$3 if ! __dnvm_has "curl"; then printf "%b\n" "${Red}$_DNVM_COMMAND_NAME needs curl to proceed. ${RCol}" >&2; @@ -85,12 +109,14 @@ __dnvm_find_latest() { local packageId="$_DNVM_RUNTIME_PACKAGE_NAME-$platform" else #dnx-coreclr-linux-x64 - local packageId="$_DNVM_RUNTIME_PACKAGE_NAME-$platform-$(__dnvm_current_os)-$arch" + local packageId="$_DNVM_RUNTIME_PACKAGE_NAME-$platform-$os-$arch" fi + local url="$DNX_ACTIVE_FEED/GetUpdates()?packageIds=%27$packageId%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false" xml="$(curl $url 2>/dev/null)" echo $xml | grep \<[a-zA-Z]:Version\>* >> /dev/null || return 1 version="$(echo $xml | sed 's/.*<[a-zA-Z]:Version>\([^<]*\).*/\1/')" + echo $version } @@ -129,6 +155,15 @@ __dnvm_package_arch() { fi } +__dnvm_package_os() { + local runtimeFullName="$1" + if [[ "$runtimeFullName" =~ "mono" ]]; then + echo "linux/darwin" + else + echo "$runtimeFullName" | sed "s/$_DNVM_RUNTIME_PACKAGE_NAME-[^-.]*-\([^.-]*\).*/\1/" + fi +} + __dnvm_update_self() { local dnvmFileLocation="$_DNVM_DNVM_DIR/dnvm.sh" if [ ! -e $dnvmFileLocation ]; then @@ -212,16 +247,19 @@ __dnvm_unpack() { #Set shell commands as executable find "$runtimeFolder/bin/" -type f \ - -exec sh -c "head -c 20 {} | grep '/usr/bin/env bash\|/bin/bash' > /dev/null" \; -print | xargs chmod 775 + -exec sh -c "head -c 20 {} | grep '/usr/bin/env bash\|/bin/bash' > /dev/null" \; -print | xargs -r chmod 775 #Set dnx to be executable - chmod 775 "$runtimeFolder/bin/dnx" + if [[ -s "$runtimeFolder/bin/dnx" ]]; then + chmod 775 "$runtimeFolder/bin/dnx" + fi } __dnvm_requested_version_or_alias() { local versionOrAlias="$1" local runtime="$2" local arch="$3" + local os="$4" local runtimeBin=$(__dnvm_locate_runtime_bin_from_full_name "$versionOrAlias") # If the name specified is an existing package, just use it as is @@ -233,18 +271,17 @@ __dnvm_requested_version_or_alias() { echo "$runtimeFullName" else local pkgVersion=$versionOrAlias + local pkgArchitecture="x64" + local pkgSystem=$os if [[ -z $runtime || "$runtime" == "mono" ]]; then echo "$_DNVM_RUNTIME_PACKAGE_NAME-mono.$pkgVersion" - elif [[ "$runtime" == "coreclr" ]]; then - local pkgArchitecture="x64" - local pkgSystem=$(__dnvm_current_os) - + else if [ "$arch" != "" ]; then local pkgArchitecture="$arch" fi - echo "$_DNVM_RUNTIME_PACKAGE_NAME-coreclr-$pkgSystem-$pkgArchitecture.$pkgVersion" + echo "$_DNVM_RUNTIME_PACKAGE_NAME-$runtime-$pkgSystem-$pkgArchitecture.$pkgVersion" fi fi fi @@ -303,10 +340,11 @@ __dnvm_help() { echo " -u|unstable use unstable feed. Installs the $_DNVM_RUNTIME_SHORT_NAME from the unstable unstable feed" echo " -r|runtime The runtime flavor to install [clr or coreclr] (default: clr)" echo "" - printf "%b\n" "${Yel}$_DNVM_COMMAND_NAME install |||latest [-a|-alias ] [-p|-persistent] [-f|-force] [-u|-unstable] ${RCol}" + printf "%b\n" "${Yel}$_DNVM_COMMAND_NAME install |||latest [-r ] [-OS ] [-a|-alias ] [-p|-persistent] [-f|-force] [-u|-unstable] ${RCol}" echo " | install requested $_DNVM_RUNTIME_SHORT_NAME from feed" echo " install requested $_DNVM_RUNTIME_SHORT_NAME from local package on filesystem" echo " latest install latest version of $_DNVM_RUNTIME_SHORT_NAME from feed" + echo " -OS the operating system that the runtime targets (default:$(__dnvm_current_os)" echo " -a|-alias set alias for requested $_DNVM_RUNTIME_SHORT_NAME on install" echo " -p|-persistent set installed version as default" echo " -f|force force install. Overwrite existing version of $_DNVM_RUNTIME_SHORT_NAME if already installed" @@ -336,7 +374,9 @@ __dnvm_help() { echo " runs the specified command in the context of the specified version of the runtime without affecting the current PATH" echo " example: $_DNVM_COMMAND_NAME exec 1.0.0-beta4 $_DNVM_PACKAGE_MANAGER_NAME build" echo "" - printf "%b\n" "${Yel}$_DNVM_COMMAND_NAME list ${RCol}" + printf "%b\n" "${Yel}$_DNVM_COMMAND_NAME list [-detailed]${RCol}" + echo " -detailed display more detailed information on each runtime" + echo "" echo " list $_DNVM_RUNTIME_SHORT_NAME versions installed " echo "" printf "%b\n" "${Yel}$_DNVM_COMMAND_NAME alias ${RCol}" @@ -391,8 +431,9 @@ dnvm() local alias= local force= local unstable= - local runtime="mono" - local arch="x64" + local os= + local runtime= + local arch= while [ $# -ne 0 ] do if [[ $1 == "-p" || $1 == "-persistent" ]]; then @@ -407,6 +448,9 @@ dnvm() elif [[ $1 == "-r" || $1 == "-runtime" ]]; then local runtime=$2 shift + elif [[ $1 == "-OS" ]]; then + local os=$2 + shift elif [[ $1 == "-arch" ]]; then local arch=$2 shift @@ -416,11 +460,6 @@ dnvm() return 1 fi - if [[ $arch == "x86" && $runtime == "coreclr" ]]; then - printf "%b\n" "${Red}Core CLR doesn't currently have a 32 bit build. You must use x64.${RCol}" - return 1 - fi - elif [[ -n $1 ]]; then [[ -n $versionOrAlias ]] && echo "Invalid option $1" && __dnvm_help && return 1 local versionOrAlias=$1 @@ -428,6 +467,11 @@ dnvm() shift done + if [[ $arch == "x86" && $runtime == "coreclr" && $os != "win" ]]; then + printf "%b\n" "${Red}Core CLR doesn't currently have a 32 bit build. You must use x64.${RCol}" + return 1 + fi + if [ -z $unstable ]; then DNX_ACTIVE_FEED="$DNX_FEED" if [ -z "$DNX_ACTIVE_FEED" ]; then @@ -444,13 +488,28 @@ dnvm() fi fi + if [[ -z $os ]]; then + os=$(__dnvm_current_os) + fi + if [[ $os == "osx" ]]; then + os="darwin" + fi + + if [[ -z $runtime ]]; then + runtime=$(__dnvm_os_runtime_defaults "$os") + fi + + if [[ -z $arch ]]; then + arch=$(__dnvm_runtime_bitness_defaults "$runtime") + fi + if [[ $runtime == "mono" ]] && ! __dnvm_has "mono"; then printf "%b\n" "${Yel}It appears you don't have Mono available. Remember to get Mono before trying to run $DNVM_RUNTIME_SHORT_NAME application. ${RCol}" >&2; fi if [[ "$versionOrAlias" == "latest" ]]; then echo "Determining latest version" - versionOrAlias=$(__dnvm_find_latest "$runtime" "$arch") + versionOrAlias=$(__dnvm_find_latest "$runtime" "$arch" "$os") [[ $? == 1 ]] && echo "Error: Could not find latest version from feed $DNX_ACTIVE_FEED" && return 1 printf "%b\n" "Latest version is ${Cya}$versionOrAlias ${RCol}" fi @@ -478,12 +537,14 @@ dnvm() $_DNVM_COMMAND_NAME use "$runtimeVersion" "$persistent" -r "$runtimeClr" [[ -n $alias ]] && $_DNVM_COMMAND_NAME alias "$alias" "$runtimeVersion" else - local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch") + local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch" "$os") local runtimeFolder="$_DNVM_USER_PACKAGES/$runtimeFullName" __dnvm_download "$runtimeFullName" "$runtimeFolder" "$force" [[ $? == 1 ]] && return 1 - $_DNVM_COMMAND_NAME use "$versionOrAlias" "$persistent" "-runtime" "$runtime" "-arch" "$arch" - [[ -n $alias ]] && $_DNVM_COMMAND_NAME alias "$alias" "$versionOrAlias" + if [[ "$os" == $(__dnvm_current_os) ]]; then + $_DNVM_COMMAND_NAME use "$versionOrAlias" "$persistent" "-runtime" "$runtime" "-arch" "$arch" + [[ -n $alias ]] && $_DNVM_COMMAND_NAME alias "$alias" "$versionOrAlias" + fi fi ;; @@ -533,7 +594,7 @@ dnvm() return 0 fi - local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch") + local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch" "$(__dnvm_current_os)") local runtimeBin=$(__dnvm_locate_runtime_bin_from_full_name "$runtimeFullName") if [[ -z $runtimeBin ]]; then @@ -612,11 +673,14 @@ dnvm() elif [[ $1 == "-r" || $1 == "-runtime" ]]; then local runtime=$2 shift + elif [[ $1 == "-OS" ]]; then + local os=$2 + shift fi shift done - local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch") + local runtimeFullName=$(__dnvm_requested_version_or_alias "$versionOrAlias" "$runtime" "$arch" "$os") [[ ! -d "$_DNVM_USER_PACKAGES/$runtimeFullName" ]] && echo "$runtimeFullName is not an installed $_DNVM_RUNTIME_SHORT_NAME version" && return 1 @@ -642,10 +706,6 @@ dnvm() [[ ! -d $_DNVM_USER_PACKAGES ]] && echo "$_DNVM_RUNTIME_FRIENDLY_NAME is not installed." && return 1 local searchGlob="$_DNVM_RUNTIME_PACKAGE_NAME-*" - if [ $# == 2 ]; then - local versionOrAlias=$2 - local searchGlob=$(__dnvm_requested_version_or_alias "$versionOrAlias") - fi echo "" # Separate empty array declaration from initialization @@ -663,9 +723,15 @@ dnvm() done fi - local formatString="%-6s %-20s %-7s %-4s %-20s %s\n" - printf "$formatString" "Active" "Version" "Runtime" "Arch" "Location" "Alias" - printf "$formatString" "------" "-------" "-------" "----" "--------" "-----" + if [[ $2 == "-detailed" ]]; then + local formatString="%-6s %-20s %-7s %-4s %-15s %-20s %s\n" + printf "$formatString" "Active" "Version" "Runtime" "Arch" "OperatingSystem" "Location" "Alias" + printf "$formatString" "------" "-------" "-------" "----" "---------------" "--------" "-----" + else + local formatString="%-6s %-20s %-7s %-4s %-15s %s\n" + printf "$formatString" "Active" "Version" "Runtime" "Arch" "OperatingSystem" "Alias" + printf "$formatString" "------" "-------" "-------" "----" "---------------" "-----" + fi local formattedHome=`(echo $_DNVM_USER_PACKAGES | sed s=$HOME=~=g)` for f in $(find $_DNVM_USER_PACKAGES -name "$searchGlob" \( -type d -or -type l \) -prune -exec basename {} \;); do @@ -675,6 +741,7 @@ dnvm() local pkgName=$(__dnvm_package_name "$f") local pkgVersion=$(__dnvm_package_version "$f") local pkgArch=$(__dnvm_package_arch "$f") + local pkgOs=$(__dnvm_package_os "$f") local alias="" local delim="" @@ -685,12 +752,14 @@ dnvm() fi done - printf "$formatString" "$active" "$pkgVersion" "$pkgRuntime" "$pkgArch" "$formattedHome" "$alias" - [[ $# == 2 ]] && echo "" && return 0 + if [[ $2 == "-detailed" ]]; then + printf "$formatString" "$active" "$pkgVersion" "$pkgRuntime" "$pkgArch" "$pkgOs" "$formattedHome" "$alias" + else + printf "$formatString" "$active" "$pkgVersion" "$pkgRuntime" "$pkgArch" "$pkgOs" "$alias" + fi done echo "" - [[ $# == 2 ]] && echo "$versionOrAlias not found" && return 1 ;; *)