Repository: pyenv-win/pyenv-win (language: python)

Issue:
Add Installer
Add an installer script, so users don't have to mess with copying files and setting up env vars just to use pyenv. I envision this being used similar to how the [poetry installer](https://python-poetry.org/docs/master/#installing-with-the-official-installer) works: Provide a single PowerShell command that users run to download and install everything.

Notes:
- When updating an existing pyenv installation, the script keeps the `install_cache/` and `versions/` folders, and wipes out everything else. Is this sufficient? Is there anything else that should be preserved during an upgrade?
- I opted to have the installer automatically run `pyenv rehash` during installation, since I couldn't think of a reason someone would install pyenv and not want to immediately run `rehash`. Is this ok?
- I rearranged the README to make the installer script the "recommended" way to install. If you'd rather, I can try to incorporate it as just another installation method, but I found it simpler to just pull it out into its own section for now.

TODO:
- [x] Update instructions in README
- [x] Add ability to update an existing pyenv installation, without forceably overwriting it
- [x] Add uninstall


Discussion / hints:

Fix patch:
diff --git a/.github/scripts/ps1.sh b/.github/scripts/ps1.sh
new file mode 100644
index 00000000..9f52c1d4
--- /dev/null
+++ b/.github/scripts/ps1.sh
@@ -0,0 +1,10 @@
+pyenv --version
+pyenv update
+pyenv install -q 3.7.4
+pyenv global 3.7.4
+pyenv versions
+python --version
+pip install --user --upgrade pip
+pip install -r $HOME/requirements_dev.txt
+pyenv rehash
+PYTHONPATH=. python -m pytest -v -s --cache-clear --cov=pyenv-win $HOME/tests
diff --git a/README.md b/README.md
index ad2f5278..b87a80fa 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,17 @@ This project was forked from [rbenv-win][3] and modified for [pyenv][1]. It is n
 
 ## Installation
 
-### Get pyenv-win
+### Installer
+
+The easiest way to install pyenv-win is to run the following command in a PowerShell terminal:
+
+```pwsh
+Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; "./install-pyenv-win.ps1"
+```
+
+Installation is complete!
+
+### Alternate installation methods
 
 Get pyenv-win via one of the following methods:
 
@@ -117,8 +127,6 @@ Get pyenv-win via one of the following methods:
 - **With [Chocolatey](https://chocolatey.org/packages/pyenv-win)**
    - `choco install pyenv-win` (this also installs all environment variables)
 
-### Finish the installation
-
 **NOTE:** If you are running Windows 10 1905 or newer, you might need to disable the built-in Python launcher via Start > "Manage App Execution Aliases" and turning off the "App Installer" aliases for Python
 
    If you installed using Chocolatey, you can skip to step 3.
@@ -196,6 +204,8 @@ Now follow the steps to "[finish the installation](#finish-the-installation)".
 - If installed via zip
    - Download the latest zip and extract it
    - Go to `%USERPROFILE%\.pyenv\pyenv-win` and replace the folders `libexec` and `bin` with the new ones you just downloaded
+- If installed via the installer
+   - Run the following in a Powershell terminal: `&"${env:PYENV_HOME}\install-pyenv-win.ps1"`
 
 ## FAQ
 
diff --git a/pyenv-win/install-pyenv-win.ps1 b/pyenv-win/install-pyenv-win.ps1
new file mode 100644
index 00000000..d9b3ac42
--- /dev/null
+++ b/pyenv-win/install-pyenv-win.ps1
@@ -0,0 +1,153 @@
+<#
+    .SYNOPSIS
+    Installs pyenv-win
+
+    .DESCRIPTION
+    Installs pyenv-win to $HOME\.pyenv
+    If pyenv-win is already installed, try to update to the latest version.
+
+    .PARAMETER Uninstall
+    Uninstall pyenv-win. Note that this uninstalls any Python versions that were installed with pyenv-win.
+
+    .INPUTS
+    None.
+
+    .OUTPUTS
+    None.
+
+    .EXAMPLE
+    PS> install-pyenv-win.ps1
+
+    .LINK
+    Online version: https://pyenv-win.github.io/pyenv-win/
+#>
+    
+param (
+    [Switch] $Uninstall = $False
+)
+    
+$PyEnvDir = "${env:USERPROFILE}\.pyenv"
+$PyEnvWinDir = "${PyEnvDir}\pyenv-win"
+$BinPath = "${PyEnvWinDir}\bin"
+$ShimsPath = "${PyEnvWinDir}\shims"
+    
+Function Remove-PyEnvVars() {
+    $PathParts = [System.Environment]::GetEnvironmentVariable('PATH', "User") -Split ";"
+    $NewPathParts = $PathParts.Where{ $_ -ne $BinPath }.Where{ $_ -ne $ShimsPath }
+    $NewPath = $NewPathParts -Join ";"
+    [System.Environment]::SetEnvironmentVariable('PATH', $NewPath, "User")
+
+    [System.Environment]::SetEnvironmentVariable('PYENV', $null, "User")
+    [System.Environment]::SetEnvironmentVariable('PYENV_ROOT', $null, "User")
+    [System.Environment]::SetEnvironmentVariable('PYENV_HOME', $null, "User")
+}
+
+Function Remove-PyEnv() {
+    Write-Host "Removing $PyEnvDir..."
+    If (Test-Path $PyEnvDir) {
+        Remove-Item -Path $PyEnvDir -Recurse
+    }
+    Write-Host "Removing environment variables..."
+    Remove-PyEnvVars
+}
+
+Function Get-CurrentVersion() {
+    $VersionFilePath = "$PyEnvDir\.version"
+    If (Test-Path $VersionFilePath) {
+        $CurrentVersion = Get-Content $VersionFilePath
+    }
+    Else {
+        $CurrentVersion = ""
+    }
+
+    Return $CurrentVersion
+}
+
+Function Get-LatestVersion() {
+    $LatestVersionFilePath = "$PyEnvDir\latest.version"
+    (New-Object System.Net.WebClient).DownloadFile("https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/.version", $LatestVersionFilePath)
+    $LatestVersion = Get-Content $LatestVersionFilePath
+
+    Remove-Item -Path $LatestVersionFilePath
+
+    Return $LatestVersion
+}
+
+Function Main() {
+    If ($Uninstall) {
+        Remove-PyEnv
+        If ($LastExitCode -eq 0) {
+            Write-Host "pyenv-win successfully uninstalled."
+        }
+        Else {
+            Write-Host "Uninstallation failed."
+        }
+        exit
+    }
+
+    $BackupDir = "${env:Temp}/pyenv-win-backup"
+    
+    $CurrentVersion = Get-CurrentVersion
+    If ($CurrentVersion) {
+        Write-Host "pyenv-win $CurrentVersion installed."
+        $LatestVersion = Get-LatestVersion
+        If ($CurrentVersion -eq $LatestVersion) {
+            Write-Host "No updates available."
+            exit
+        }
+        Else {
+            Write-Host "New version available: $LatestVersion. Updating..."
+            
+            Write-Host "Backing up existing Python installations..."
+            $FoldersToBackup = "install_cache", "versions", "shims"
+            ForEach ($Dir in $FoldersToBackup) {
+                If (-not (Test-Path $BackupDir)) {
+                    New-Item -ItemType Directory -Path $BackupDir
+                }
+                Move-Item -Path "${PyEnvWinDir}/${Dir}" -Destination $BackupDir
+            }
+            
+            Write-Host "Removing $PyEnvDir..."
+            Remove-Item -Path $PyEnvDir -Recurse
+        }   
+    }
+
+    New-Item -Path $PyEnvDir -ItemType Directory
+
+    $DownloadPath = "$PyEnvDir\pyenv-win.zip"
+
+    (New-Object System.Net.WebClient).DownloadFile("https://github.com/pyenv-win/pyenv-win/archive/master.zip", $DownloadPath)
+    Expand-Archive -Path $DownloadPath -DestinationPath $PyEnvDir
+    Move-Item -Path "$PyEnvDir\pyenv-win-master\*" -Destination "$PyEnvDir"
+    Remove-Item -Path "$PyEnvDir\pyenv-win-master" -Recurse
+    Remove-Item -Path $DownloadPath
+
+    # Update env vars
+    [System.Environment]::SetEnvironmentVariable('PYENV', "${PyEnvWinDir}\", "User")
+    [System.Environment]::SetEnvironmentVariable('PYENV_ROOT', "${PyEnvWinDir}\", "User")
+    [System.Environment]::SetEnvironmentVariable('PYENV_HOME', "${PyEnvWinDir}\", "User")
+
+    $PathParts = [System.Environment]::GetEnvironmentVariable('PATH', "User") -Split ";"
+
+    # Remove existing paths, so we don't add duplicates
+    $NewPathParts = $PathParts.Where{ $_ -ne $BinPath }.Where{ $_ -ne $ShimsPath }
+    $NewPathParts = ($BinPath, $ShimsPath) + $NewPathParts
+    $NewPath = $NewPathParts -Join ";"
+    [System.Environment]::SetEnvironmentVariable('PATH', $NewPath, "User")
+
+    If (Test-Path $BackupDir) {
+        Write-Host "Restoring Python installations..."
+        Move-Item -Path "$BackupDir/*" -Destination $PyEnvWinDir
+    }
+    
+    &"$BinPath\pyenv.ps1" --version
+
+    If ($LastExitCode -eq 0) {
+        Write-Host "pyenv-win is successfully installed. You may need to close and reopen your terminal before using it."
+    }
+    Else {
+        Write-Host "pyenv-win was not installed successfully. If this issue persists, please open a ticket: https://github.com/pyenv-win/pyenv-win/issues."
+    }
+}
+
+Main


Test patch:
diff --git a/.github/workflows/pytest_ps1.yml b/.github/workflows/pytest_ps1.yml
new file mode 100644
index 00000000..b0aaef43
--- /dev/null
+++ b/.github/workflows/pytest_ps1.yml
@@ -0,0 +1,32 @@
+name: pytest_ps1
+
+on:
+  push:
+    branches:
+      - '**'
+  pull_request:
+    branches: [ master ]
+
+  # Allows you to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+jobs:
+  build:
+    name: pyenv-win pytest_ps1
+    runs-on: windows-latest
+    env:
+      HOME: D:/a/pyenv-win/pyenv-win
+    steps:
+
+      - name: checkout
+        uses: actions/checkout@v2
+
+      - name: pytest_ps1 pwsh command
+        shell: pwsh
+        run : |
+          Set-PSRepository PSGallery -InstallationPolicy Trusted
+          Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; "./install-pyenv-win.ps1"
+
+      - name: pytest bash script
+        run: ${{ env.HOME }}/.github/scripts/ps1.sh
+        shell: bash