install.ps1 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. # From: https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor/install.ps1
  2. #
  3. #
  4. # Sample script to install Python and pip under Windows
  5. # Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
  6. # License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
  7. $MINICONDA_URL = "http://repo.continuum.io/miniconda/"
  8. $BASE_URL = "https://www.python.org/ftp/python/"
  9. $GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
  10. $GET_PIP_PATH = "C:\get-pip.py"
  11. $PYTHON_PRERELEASE_REGEX = @"
  12. (?x)
  13. (?<major>\d+)
  14. \.
  15. (?<minor>\d+)
  16. \.
  17. (?<micro>\d+)
  18. (?<prerelease>[a-z]{1,2}\d+)
  19. "@
  20. function Download ($filename, $url) {
  21. $webclient = New-Object System.Net.WebClient
  22. $basedir = $pwd.Path + "\"
  23. $filepath = $basedir + $filename
  24. if (Test-Path $filename) {
  25. Write-Host "Reusing" $filepath
  26. return $filepath
  27. }
  28. # Download and retry up to 3 times in case of network transient errors.
  29. Write-Host "Downloading" $filename "from" $url
  30. $retry_attempts = 2
  31. for ($i = 0; $i -lt $retry_attempts; $i++) {
  32. try {
  33. $webclient.DownloadFile($url, $filepath)
  34. break
  35. }
  36. Catch [Exception]{
  37. Start-Sleep 1
  38. }
  39. }
  40. if (Test-Path $filepath) {
  41. Write-Host "File saved at" $filepath
  42. } else {
  43. # Retry once to get the error message if any at the last try
  44. $webclient.DownloadFile($url, $filepath)
  45. }
  46. return $filepath
  47. }
  48. function ParsePythonVersion ($python_version) {
  49. if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
  50. return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
  51. $matches.prerelease)
  52. }
  53. $version_obj = [version]$python_version
  54. return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
  55. }
  56. function DownloadPython ($python_version, $platform_suffix) {
  57. $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
  58. if (($major -le 2 -and $micro -eq 0) `
  59. -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
  60. ) {
  61. $dir = "$major.$minor"
  62. $python_version = "$major.$minor$prerelease"
  63. } else {
  64. $dir = "$major.$minor.$micro"
  65. }
  66. if ($prerelease) {
  67. if (($major -le 2) `
  68. -or ($major -eq 3 -and $minor -eq 1) `
  69. -or ($major -eq 3 -and $minor -eq 2) `
  70. -or ($major -eq 3 -and $minor -eq 3) `
  71. ) {
  72. $dir = "$dir/prev"
  73. }
  74. }
  75. if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
  76. $ext = "msi"
  77. if ($platform_suffix) {
  78. $platform_suffix = ".$platform_suffix"
  79. }
  80. } else {
  81. $ext = "exe"
  82. if ($platform_suffix) {
  83. $platform_suffix = "-$platform_suffix"
  84. }
  85. }
  86. $filename = "python-$python_version$platform_suffix.$ext"
  87. $url = "$BASE_URL$dir/$filename"
  88. $filepath = Download $filename $url
  89. return $filepath
  90. }
  91. function InstallPython ($python_version, $architecture, $python_home) {
  92. Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
  93. if (Test-Path $python_home) {
  94. Write-Host $python_home "already exists, skipping."
  95. return $false
  96. }
  97. if ($architecture -eq "32") {
  98. $platform_suffix = ""
  99. } else {
  100. $platform_suffix = "amd64"
  101. }
  102. $installer_path = DownloadPython $python_version $platform_suffix
  103. $installer_ext = [System.IO.Path]::GetExtension($installer_path)
  104. Write-Host "Installing $installer_path to $python_home"
  105. $install_log = $python_home + ".log"
  106. if ($installer_ext -eq '.msi') {
  107. InstallPythonMSI $installer_path $python_home $install_log
  108. } else {
  109. InstallPythonEXE $installer_path $python_home $install_log
  110. }
  111. if (Test-Path $python_home) {
  112. Write-Host "Python $python_version ($architecture) installation complete"
  113. } else {
  114. Write-Host "Failed to install Python in $python_home"
  115. Get-Content -Path $install_log
  116. Exit 1
  117. }
  118. }
  119. function InstallPythonEXE ($exepath, $python_home, $install_log) {
  120. $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
  121. RunCommand $exepath $install_args
  122. }
  123. function InstallPythonMSI ($msipath, $python_home, $install_log) {
  124. $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
  125. $uninstall_args = "/qn /x $msipath"
  126. RunCommand "msiexec.exe" $install_args
  127. if (-not(Test-Path $python_home)) {
  128. Write-Host "Python seems to be installed else-where, reinstalling."
  129. RunCommand "msiexec.exe" $uninstall_args
  130. RunCommand "msiexec.exe" $install_args
  131. }
  132. }
  133. function RunCommand ($command, $command_args) {
  134. Write-Host $command $command_args
  135. Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
  136. }
  137. function InstallPip ($python_home) {
  138. $pip_path = $python_home + "\Scripts\pip.exe"
  139. $python_path = $python_home + "\python.exe"
  140. if (-not(Test-Path $pip_path)) {
  141. Write-Host "Installing pip..."
  142. $webclient = New-Object System.Net.WebClient
  143. $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
  144. Write-Host "Executing:" $python_path $GET_PIP_PATH
  145. & $python_path $GET_PIP_PATH
  146. } else {
  147. Write-Host "pip already installed."
  148. }
  149. }
  150. function DownloadMiniconda ($python_version, $platform_suffix) {
  151. if ($python_version -eq "3.4") {
  152. $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
  153. } else {
  154. $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
  155. }
  156. $url = $MINICONDA_URL + $filename
  157. $filepath = Download $filename $url
  158. return $filepath
  159. }
  160. function InstallMiniconda ($python_version, $architecture, $python_home) {
  161. Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
  162. if (Test-Path $python_home) {
  163. Write-Host $python_home "already exists, skipping."
  164. return $false
  165. }
  166. if ($architecture -eq "32") {
  167. $platform_suffix = "x86"
  168. } else {
  169. $platform_suffix = "x86_64"
  170. }
  171. $filepath = DownloadMiniconda $python_version $platform_suffix
  172. Write-Host "Installing" $filepath "to" $python_home
  173. $install_log = $python_home + ".log"
  174. $args = "/S /D=$python_home"
  175. Write-Host $filepath $args
  176. Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
  177. if (Test-Path $python_home) {
  178. Write-Host "Python $python_version ($architecture) installation complete"
  179. } else {
  180. Write-Host "Failed to install Python in $python_home"
  181. Get-Content -Path $install_log
  182. Exit 1
  183. }
  184. }
  185. function InstallMinicondaPip ($python_home) {
  186. $pip_path = $python_home + "\Scripts\pip.exe"
  187. $conda_path = $python_home + "\Scripts\conda.exe"
  188. if (-not(Test-Path $pip_path)) {
  189. Write-Host "Installing pip..."
  190. $args = "install --yes pip"
  191. Write-Host $conda_path $args
  192. Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
  193. } else {
  194. Write-Host "pip already installed."
  195. }
  196. }
  197. function main () {
  198. InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
  199. InstallPip $env:PYTHON
  200. }
  201. main