diff --git a/DEMO.png b/DEMO.png deleted file mode 100644 index 2aeb65b..0000000 Binary files a/DEMO.png and /dev/null differ diff --git a/README.md b/README.md index b8bdac0..c61bdf9 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,108 @@ -## EB CLI Installer +# EB CLI Installer ------- - -### 1. Overview - ------- +## 1. Overview This repository hosts scripts to generate self-contained installations of the [EB CLI](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3.html). ------- +### 1.1. Prerequisites +You will need to have the following prerequisites installed before running the install script. -### 1.1. Prerequisites +* **Git** + * If not already installed you can download git from the [Git downloads page](https://git-scm.com/downloads). +* **Python** + * We recommend that you install Python using the [pyenv](https://github.com/pyenv/pyenv) Python version manager. Alternately, you can download Python from the [Python downloads page](https://www.python.org/downloads/). +* **virtualenv** + * Follow the [virtualenv documentation](https://virtualenv.pypa.io/en/latest/installation.html) to install virtualenv. -If you don't have Git, install it from [Git Downloads](https://git-scm.com/downloads). +## 2. Quick start -Python, which the EBCLI Installer depends on, requires the following prerequisites for each operating system. +### 2.1. Clone this repository -- **Linux** - - **Ubuntu and Debian** +Use the following: - ```shell - build-essential zlib1g-dev libssl-dev libncurses-dev libffi-dev libsqlite3-dev libreadline-dev libbz2-dev - ``` +``` +git clone https://github.com/aws/aws-elastic-beanstalk-cli-setup.git +``` - - **Amazon Linux and Fedora** +### 2.2. Install/Upgrade the EB CLI - ```shell - "Development Tools" zlib-devel openssl-devel ncurses-devel libffi-devel sqlite-devel.x86_64 readline-devel.x86_64 bzip2-devel.x86_64 - ``` +#### MacOS/Linux +On **Bash** or **Zsh**: -- **macOS** +``` +python ./aws-elastic-beanstalk-cli-setup/scripts/ebcli_installer.py +``` + +#### Windows +In **PowerShell** or in a **Command Prompt** window: - ```shell - Xcode openssl zlib readline - ``` +``` +python .\aws-elastic-beanstalk-cli-setup\scripts\ebcli_installer.py +``` ------- +### 2.3. After installation -### 2. Use +On Linux and macOS, the output contains instructions to add the EB CLI (and Python) executable file to the shell's `$PATH` variable, if it isn't already in it. ------- +## 3. Usage -#### 2.1. Clone this repository +The `ebcli_installer.py` Python script will install the [awsebcli](https://pypi.org/project/awsebcli/) package in a virtual environment to prevent potential conflicts with other Python packages. -Use the following: +For most use cases you can execute the `ebcli_installer.py` script with no arguments. -```shell -git clone https://github.com/aws/aws-elastic-beanstalk-cli-setup.git +``` +python ./aws-elastic-beanstalk-cli-setup/scripts/ebcli_installer.py ``` -#### 2.2. Install/Upgrade the EB CLI +### 3.1 Advanced usage -On **Bash** and **Zsh** on macOS and Linux: + - To install a **specific version** of the EB CLI: -```shell -./aws-elastic-beanstalk-cli-setup/scripts/bundled_installer -``` + ```shell + python scripts/ebcli_installer.py --version 3.14.13 + ``` -In **PowerShell** or in a **Command Prompt** window: + - To install the EB CLI with a specific **version of Python** (the Python version doesn't need to be in `$PATH`): + + ```shell + python scripts/ebcli_installer.py --python-installation /path/to/some/python/on/your/computer + ``` + + - To install the EB CLI **from source** (Git repository, .tar file, .zip file): + ```shell + python scripts/ebcli_installer.py --ebcli-source /path/to/awsebcli.zip + + python scripts/ebcli_installer.py --ebcli-source /path/to/EBCLI/codebase/on/your/computer + ``` + - To install the EB CLI at a **specific location**, instead of in the standard `.ebcli-virtual-env` directory in the user's home directory: -```ps1 -.\aws-elastic-beanstalk-cli-setup\scripts\bundled_installer + ```shell + python scripts/ebcli_installer.py --location /path/to/ebcli/installation/location + ``` +### 3.2 Options + +``` +options: + -h, --help show this help message and exit + -e VIRTUALENV_EXECUTABLE, --virtualenv-executable VIRTUALENV_EXECUTABLE + path to the virtualenv installation to use to create the EBCLI's virtualenv + -i, --hide-export-recommendation + boolean to hide recommendation to modify PATH + -l LOCATION, --location LOCATION + location to store the awsebcli packages and its dependencies in + -p PYTHON_INSTALLATION, --python-installation PYTHON_INSTALLATION + path to the python installation under which to install the awsebcli and its + dependencies + -q, --quiet enable quiet mode to display only minimal, necessary output + -s EBCLI_SOURCE, --ebcli-source EBCLI_SOURCE + filesystem path to a Git repository of the EBCLI, or a .zip or .tar file of + the EBCLI source code; useful when testing a development version of the EBCLI. + -v VERSION, --version VERSION + version of EBCLI to install ``` -#### 2.3. Troubleshooting +## 4. Troubleshooting - **Linux** @@ -110,123 +148,34 @@ In **PowerShell** or in a **Command Prompt** window: pip install virtualenv python .\aws-elastic-beanstalk-cli-setup\scripts\ebcli_installer.py ``` +## 5. Frequently asked questions -#### 2.4. After installation - -On Linux and macOS, the output contains instructions to add the EB CLI (and Python) executable file to the shell's `$PATH` variable, if it isn't already in it. - -#### 2.5. Demo execution of `bundled_installer` - -![Demo](./DEMO.png) - -### 3. Advanced use - -To install the EB CLI, `bundled_installer` runs `ebcli_installer.py`. `ebcli_installer.py` has the following capabilities: - - - To install a **specific version** of the EB CLI: - - ```shell - python scripts/ebcli_installer.py --version 3.14.13 - ``` - - - To install the EB CLI with a specific **version of Python** (the Python version doesn't need to be in `$PATH`): - - ```shell - python scripts/ebcli_installer.py --python-installation /path/to/some/python/on/your/computer - ``` - - - To install the EB CLI **from source** (Git repository, .tar file, .zip file): - ```shell - python scripts/ebcli_installer.py --ebcli-source /path/to/awsebcli.zip - - python scripts/ebcli_installer.py --ebcli-source /path/to/EBCLI/codebase/on/your/computer - ``` - - To install the EB CLI at a **specific location**, instead of in the standard `.ebcli-virtual-env` directory in the user's home directory: - - ```shell - python scripts/ebcli_installer.py --location /path/to/ebcli/installation/location - ``` - -Run the following command to view the help text for `ebcli_installer.py`: - -```shell -python scripts/ebcli_installer.py --help -``` +### 5.1. For the **experienced Python developer**, what's the advantage of this mode of installation instead of regular `pip` inside a `virtualenv`? -### 4. Frequently asked questions +Even within a `virtualenv`, a developer might need to install multiple packages whose dependencies are in conflict. For example, at times the AWS CLI and the EB CLI have used conflicting versions of `botocore`. [One such instance](https://github.com/aws/aws-cli/issues/3550) was particularly egregious. When there are conflicts, users have to manage separate `virtualenvs` for each of the conflicting packages, or find a combination of the packages without conflicts. ------- +Both of these workarounds become unmanageable over time, and as the number of packages that are in conflict increases. -#### 4.1. Can I skip the Python installation? - -**Yes.** If you already have Python installed on your system, after step `2.1.`, run the following. - -On **Bash** and **Zsh**: - -```shell -python aws-elastic-beanstalk-cli-setup/scripts/ebcli_installer.py -``` - -In **PowerShell** and from the **Command Prompt** window: - -```shell -python .\aws-elastic-beanstalk-cli-setup\scripts\ebcli_installer.py -``` - -#### 4.2. For the **experienced Python developer**, what's the advantage of this mode of installation instead of regular `pip` inside a `virtualenv`? - -Even within a `virtualenv`, a developer might need to install multiple packages whose dependencies are in conflict. For example, at times the AWS CLI and the EB -CLI have used conflicting versions of `botocore`. [One such instance](https://github.com/aws/aws-cli/issues/3550) was particularly egregious. When there are -conflicts, users have to manage separate `virtualenvs` for each of the conflicting packages, or find a combination of the packages without conflicts. -Both these workarounds become unmanageable over time, and as the number of packages that are in conflict increases. - -#### 4.3. On macOS (or Linux systems with `brew`), is this better than `brew install awsebcli`? +### 5.2. On macOS (or Linux systems with `brew`), is this better than `brew install awsebcli`? **Yes**, for these reasons: - The AWS Elastic Beanstalk team has no control over how `brew` operates. - The `brew install ...` mechanism doesn't solve the problem of dependency conflicts, which is a primary goal of this project. -#### 4.3. For developers who are **new to Python**, does this mode of installation pose challenges? - -The opinion of the AWS Elastic Beanstalk team is "**No**". - -Aside from the problem described in `4.2.`, developers new to Python are often confused by the presence of multiple versions of Python and `pip` executable files on -their system. A common problem that such developers encounter is that when they install `eb` with one `pip` executable file (presumably using the `sudo` -prefix), -no `eb`-related commands work because the correct set of directories isn't referenced correctly. - -Typically, for such developers, use of `virtualenv` is the correct path forward. However, this becomes yet another hurdle before using `eb`. - -Another common problem is where users install Python and `pip` in ways that Elastic Beanstalk Documentation doesn't recommend, such as using arbitrary Personal Package Archives -(PPAs) on Ubuntu, or similar unmaintained sources that lack scrutiny. - -#### 4.4. Can I execute the Bash scripts in a Cygwin, git-bash, or other Bash-like shell on Windows? - -**No**. At this time, we don't directly support execution on Bash-like environments on Windows. Use PowerShell or the Command Prompt window to install. You can -add the location of the `eb` and `Python` executable files to `$PATH` . - -#### 4.5. Can I execute the Bash scripts in a `fish` shell? -**Yes**, but only if you have Bash on your computer. At this time we don't provide specific guidance on how to set `$PATH` in Fish, however, Fish has [detailed documentation](https://fishshell.com/docs/current/tutorial.html#tut_path) for this purpose. - -#### 4.6. I already have Python installed. Can I still execute `bundled_installer`? - -**Yes**. It's safe to execute `bundled_installer` even if you already have Python installed. The installer will skip reinstallation. - -#### 4.7. I already have the EB CLI installed. Can I still execute `ebcli_installer.py`? +### 5.3. I already have the EB CLI installed. Can I still execute `ebcli_installer.py`? **Yes**. Consider the following two cases: -- `ebcli_installer.py` was previously run, creating `.ebcli-virtual-env` in the user's home directory (or the user's choice of a directory indicated through the -`--location` argument). In this case, the EB CLI will overwrite `.ebcli-virtual-env` and attempt to install the latest version of the EB CLI in the `virtualenv` within it. +- `ebcli_installer.py` was previously run, creating `.ebcli-virtual-env` in the user's home directory (or the user's choice of a directory indicated through the `--location` argument). In this case, the EB CLI will overwrite `.ebcli-virtual-env` and attempt to install the latest version of the EB CLI in the `virtualenv` within it. - `eb` is in `$PATH`, however, it wasn't installed by `ebcli_installer.py`. In this case, the installer will install `eb` within `.ebcli-virtual-env` in the user's home directory (or the user's choice of a directory indicated through the `--location` argument), and prompt the user to prefix `/path-to/.ebcli-virtual-env/executables` to `$PATH`. Until you perform this action, the older `eb` executable file will continue to be referenced when you type `eb`. -#### 4.8. How does `ebcli_installer.py` work? +### 5.4. How does `ebcli_installer.py` work? When executing the Python script, `ebcli_installer.py` does the following: @@ -237,24 +186,12 @@ When executing the Python script, `ebcli_installer.py` does the following: - `.bat` and `.ps1` wrappers for `eb` on Windows. - When complete, you will be prompted to add `/executables` to `$PATH`, only if the directory is not already in it. -#### 4.8. How does `bundled_installer` work? - -- On macOS or Linux, `bundled_installer` uses the extremely popular [`pyenv` project](https://github.com/pyenv/pyenv) to install the latest version of Python 3.7. -- On Windows, it downloads the MSI installer of the latest Python version from Python's website and silently installs it. - -#### 4.9. Are there dependency problems that this mode of installation doesn't solve? +### 5.5. Are there dependency problems that this mode of installation doesn't solve? Unfortunately, **yes**. Suppose the dependencies of `eb`, say `Dep A` and `Dep B`, are in conflict. Because `pip` lacks dependency management capabilities, the resulting `eb` installation might not work. -#### 4.10. Is it okay to use Python 2.7 to install the EB CLI? - -**Yes**, however, be aware that Python 2.7 will be deprecated on January 1, 2020. There won't be security updates after that date. - -Also, the latest minor version series, Python 3.7, offers significant improvements over the Python 2.7 series. We highly recommend that you use Python 3.7 -for testing purposes, even though the Elastic Beanstalk team tests the EB CLI against Python 2.7. - -### 5. License +## 6. License This library is licensed under the Mozilla Public License Version 2.0. diff --git a/VERSION b/VERSION index d917d3e..0ea3a94 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.2 +0.2.0 diff --git a/scripts/bundled_installer b/scripts/bundled_installer deleted file mode 100755 index d7cef70..0000000 --- a/scripts/bundled_installer +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash -# ****************************************************************** -# ABOUT -# ****************************************************************** -# -# This script installs: -# -# - the latest (or close to it) Python -# - the latest version of the EBCLI -export PYTHON_VERSION="3.7.9" -export PYENV_ROOT=${PYENV_ROOT:-"$HOME/.pyenv"} -export PYENV_BIN="$PYENV_ROOT/versions/$PYTHON_VERSION/bin" -BASH_PROFILE="$HOME/.bash_profile" -ZSHENV="$HOME/.zshrc" -PYTHON_ALREADY_IN_PATH=false - -function change_to_scripts_directory() { - SCRIPTS_DIRECTORY=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) - - cd "$SCRIPTS_DIRECTORY" -} - -function echo_with_colors_inverted() -{ - MESSAGE=$1 - echo -e "\033[7m$MESSAGE\033[0m" -} - -function exit_if_return_code_is_non_zero() { - if [[ $? -ne 0 ]] ; then - echo_with_indentation "Exiting due to failure" - - exit $? - fi -} - -function install_python() { - echo "" - echo_with_colors_inverted "==============================================" - echo_with_colors_inverted "I. Installing Python " - echo_with_colors_inverted "==============================================" - if [ -f python_installer ]; then - SUPPRESS_PATH_EXPORT_MESSAGE=true - source ./python_installer SUPPRESS_PATH_EXPORT_MESSAGE - exit_if_return_code_is_non_zero - fi -} - -function install_ebcli() { - echo "" - echo_with_colors_inverted "==============================================" - echo_with_colors_inverted "II. Creating self-contained EBCLI installation" - echo_with_colors_inverted "==============================================" - if [ -f ebcli_installer.py ]; then - ${PYENV_BIN}/python ./ebcli_installer.py \ - --python-installation ${PYENV_BIN}/python \ - --virtualenv-executable ${PYENV_BIN}/virtualenv - exit_if_return_code_is_non_zero - fi -} - -function print_python_path_export_message() { - if [ "${PYTHON_ALREADY_IN_PATH}" = false ]; then - print_path_export_instructions - fi -} - -change_to_scripts_directory -install_python -install_ebcli -print_python_path_export_message diff --git a/scripts/bundled_installer.bat b/scripts/bundled_installer.bat deleted file mode 100644 index 9eccd39..0000000 --- a/scripts/bundled_installer.bat +++ /dev/null @@ -1 +0,0 @@ -Powershell.exe -executionpolicy remotesigned -File "%~dp0\bundled_installer.ps1" diff --git a/scripts/bundled_installer.ps1 b/scripts/bundled_installer.ps1 deleted file mode 100644 index 11f50c6..0000000 --- a/scripts/bundled_installer.ps1 +++ /dev/null @@ -1,57 +0,0 @@ -function Write-OutputWithInvertedColors([String] $Message) { - Write-Host $Message -ForegroundColor Black -BackgroundColor White -} - -function Get-HomePath() { - if (Test-Path Env:\USERPROFILE) { - return $env:USERPROFILE - } elseif (Test-Path Env:\HOMEDRIVE -and Env:\HOMEPATH) { - return $env:HOMEDRIVE + $env:HOMEPATH - } elseif (Test-Path Env:\LOCALAPPDATA) { - return $env:LOCALAPPDATA - } elseif (Test-Path Env:\APPDATA) { - return $env:APPDATA - } else { - Write-Host "Cannot determine user's home directory." -ForegroundColor Red - Exit 1 - } -} - -function Exit-OnFailure() { - if ($LASTEXITCODE -ne 0) { - Write-Host "Exiting due to failure" -ForegroundColor Red - exit 1 - } -} - -function Update-UserEnvironmentPath { - $env:Path = - [System.Environment]::GetEnvironmentVariable("Path","Machine") + - ";" + - [System.Environment]::GetEnvironmentVariable("Path","User") -} - -function Write-StepTitle([String] $Message) { - $equals = "=" * 46 - Write-Host "" - Write-OutputWithInvertedColors $equals - Write-OutputWithInvertedColors $Message - Write-OutputWithInvertedColors $equals -} -Write-StepTitle "I. Installing Python " -powershell "$PSScriptRoot\install-python.ps1" -Exit-OnFailure -Update-UserEnvironmentPath - -Write-StepTitle "II. Creating self-contained EBCLI installation" -$HomeDir = Get-HomePath -Write-Host "Installing the EBCLI in $HomeDir\.ebcli-virtual-env" -python "$PSScriptRoot\ebcli_installer.py" --virtualenv-executable "$PSScriptRoot\virtualenv\bin\virtualenv.exe" --hide-export-recommendation --location $HomeDir -Exit-OnFailure - -$PathExporter = "$HomeDir\.ebcli-virtual-env\executables\path_exporter.vbs" -if ([System.IO.File]::Exists($PathExporter)) { - Write-StepTitle "III. Exporting `eb` PATH's " - Start-Process "cscript.exe" -ArgumentList "$HomeDir\.ebcli-virtual-env\executables\path_exporter.vbs" -Wait - Update-UserEnvironmentPath -} diff --git a/scripts/ebcli_installer.py b/scripts/ebcli_installer.py index df7637b..0e6d07e 100644 --- a/scripts/ebcli_installer.py +++ b/scripts/ebcli_installer.py @@ -3,8 +3,7 @@ Prerequisites: - 1. Python + pip (preferably Python 3.7, although Python 2.7, 3.4, 3.5, - 3.6, and 3.7 are supported) + 1. Python + pip (preferably Python 3.7) 2. virtualenv 3. Bash/Zsh on Linux/MacOS ; PowerShell/CMD Prompt on Windows @@ -13,14 +12,14 @@ To execute script: # let the script find Python in PATH - python //bundled_installer.py + python ./scripts/ebcli_installer.py # specify Python executable - python scripts/bundled_installer.py -p ~/.pyenv/versions/3.7.9/bin/python + python ./scripts/ebcli_installer.py -p ~/.pyenv/versions/3.7.12/bin/python To view help text: - python //bundled_installer.py --help + python ./scripts/ebcli_installer.py --help """ import argparse diff --git a/scripts/install-python.ps1 b/scripts/install-python.ps1 deleted file mode 100644 index 7a5fbda..0000000 --- a/scripts/install-python.ps1 +++ /dev/null @@ -1,84 +0,0 @@ -$PythonInstaller = "$PSScriptRoot\python3.7.9.exe" -$StepNumber = 1 - -function Write-StepTitle([String] $StepMessage) { - $StepMessage="$Script:StepNumber. $StepMessage" - $MessageLength=$StepMessage.length - $RepeatedStars = "*" * $MessageLength - Write-Host "" - Write-Host $RepeatedStars - Write-Host $StepMessage - Write-Host $RepeatedStars - $Script:StepNumber = $Script:StepNumber + 1 -} - -function Get-PythonExecutable { - Write-StepTitle "Looking for existing Python 3.7.9 installation." - return Get-WmiObject -Namespace "root/cimv2" -Class Win32_Product -Filter "Name Like 'Python 3.7.9 Executables%'" -} - -function Get-PythonInstallationTarget { - if ([Environment]::Is64BitOperatingSystem) { - Write-StepTitle "Downloading x64 version of Python." - return "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64-webinstall.exe" - } else { - Write-StepTitle "Downloading x86 version of Python." - return "https://www.python.org/ftp/python/3.7.9/python-3.7.9-webinstall.exe" - } -} - -function Get-PythonMSI { - if ([System.IO.File]::Exists($PythonInstaller)) { - Remove-Item $PythonInstaller - } - $url = Get-PythonInstallationTarget - $client = New-Object System.Net.WebClient - try { - [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - $client.DownloadFile($url, $PythonInstaller) - } catch { - Write-Host "Failed to download Python. The following exception was raised:" -ForegroundColor Red - Write-Host $_.exception -ForegroundColor Red - - Exit 1 - } -} - -function Install-Python { - Write-StepTitle "Installing Python. Do not close this window." - Write-Host "Installing Python. Do not close this window." - $install = Start-Process $PythonInstaller -ArgumentList "InstallAllUsers=1 PrependPath=1" -PassThru -wait - if ($install.ExitCode -eq 0) { - Write-Host "Installation completed successfully." -ForegroundColor Green - } elseif ($install.ExitCode -eq 1602) { - Write-Host "Installer was exited by the user." -ForegroundColor Red - Exit 1 - } else { - Write-Host "Installation failed with exit code $install.ExitCode" -ForegroundColor Red - Exit 1 - } -} - -function Update-UserEnvironmentPath { - Write-StepTitle "Updating Environment PATH of this shell." - $env:Path = - [System.Environment]::GetEnvironmentVariable("Path","Machine") + - ";" + - [System.Environment]::GetEnvironmentVariable("Path","User") -} - -function Install-Virtualenv { - Write-StepTitle "Installing virtualenv" - Invoke-Expression "pip install virtualenv --target $PSScriptRoot\virtualenv" -} - -$PythonExecutable = Get-PythonExecutable -if ($PythonExecutable.count -eq 0) { - Get-PythonMSI - Install-Python - Update-UserEnvironmentPath - Remove-Item $PythonInstaller -} else { - Write-Host "Python 3.7.9 is already installed." -ForegroundColor Green -} -Install-Virtualenv diff --git a/scripts/python_installer b/scripts/python_installer deleted file mode 100755 index 1693f73..0000000 --- a/scripts/python_installer +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash -# ****************************************************************** -# ABOUT -# ****************************************************************** -# -# This script installs: -# -# 1. the latest (or close to it) version of Python through the `pyenv` -# project on Linux-/Unix-based machines. -# -# 2. virtualenv within the bin/ directory of the above Python -# installation -# -# Prerequisites: -# - Git -# - Bash -# -# Usage: -# -# ./python_installer -# -# -BASH_PROFILE="$HOME/.bash_profile" -ZSHENV="$HOME/.zshrc" -COMMAND_LINE_ARGS=$* -PYTHON_VERSION=${PYTHON_VERSION:="3.7.9"} -SUPPRESS_PATH_EXPORT_MESSAGE=${SUPPRESS_PATH_EXPORT_MESSAGE:=false} -PYENV_ROOT=${PYENV_ROOT:="$HOME/.pyenv"} -export PYTHON_ALREADY_IN_PATH=false - -if [ ! -d ${PYENV_ROOT} ]; then - mkdir ${PYENV_ROOT} -fi - -PYENV_BIN=${PYENV_BIN:="$PYENV_ROOT/versions/$PYTHON_VERSION/bin"} -PYENV_REPOSITORY_LOCATION="$HOME/.pyenv-repository" -PYENV_GITHUB_LOCATION="https://github.com/pyenv/pyenv.git" -# commit associated with the pyenv release 1.2.9 -PYENV_REPOSITORY_RELEASE_CANDIDATE="3f39e8a944943b17dc8cba473d160aabc7f76796" -STEP_NUMBER=1 - - -function exit_if_return_code_is_non_zero() { - if [[ $? -ne 0 ]] ; then - echo_with_indentation "Exiting due to failure" - - exit $? - fi -} - -function echo_step_title() { - local step_message=$1 - step_message="$STEP_NUMBER. $step_message" - local message_length=${#step_message} - local repeated_stars=$(head -c ${message_length} /dev/zero | tr '\0' '*') - repeated_stars="$repeated_stars" - echo "" - echo "$repeated_stars" - echo ${step_message} - echo "$repeated_stars" - STEP_NUMBER=$(($STEP_NUMBER + 1)) -} - -function echo_with_indentation() { - local message=$1 - echo -e " $message" -} - -function echo_error_message () { - local message=$1 - echo_with_indentation "\033[38;5;9m$message\033[0m" -} - -function echo_recommendation_message() { - local message=$1 - echo_with_indentation "\033[38;5;11m$message\033[0m" -} - -function echo_success_message() { - local message=$1 - echo_with_indentation "\033[38;5;2m$message\033[0m" -} - -function print_path_export_instructions() { - echo_with_indentation "" - echo_recommendation_message " - NOTE: To complete installation, ensure \`python\` is in PATH. You can ensure this by executing:" - echo_with_indentation "" - echo_recommendation_message " 1. Bash:" - echo_with_indentation "" - echo_recommendation_message " echo 'export PATH="${PYENV_BIN}:\$PATH"' >> $BASH_PROFILE && source $BASH_PROFILE" - echo_with_indentation "" - echo_recommendation_message " 2. Zsh:" - echo_with_indentation "" - echo_recommendation_message " echo 'export PATH="${PYENV_BIN}:\$PATH"' >> $ZSHENV && source $ZSHENV" -} - -function python_is_not_in_path() { - if [[ ":$PATH:" != *":$PYENV_BIN:"* ]]; then - return 0 - fi - return 1 -} - -function install_python() { - pyenv install "$PYTHON_VERSION" --skip-existing - exit_if_return_code_is_non_zero - echo_success_message " - Python $PYTHON_VERSION is installed at $PYENV_BIN" - - if python_is_not_in_path; then - if [ ${SUPPRESS_PATH_EXPORT_MESSAGE} = false ] ; then - print_path_export_instructions - fi - else - PYTHON_ALREADY_IN_PATH=true - echo "" - if [ ${SUPPRESS_PATH_EXPORT_MESSAGE} = false ] ; then - echo_with_indentation " - $PYENV_BIN is already in PATH no further action need be taken." - fi - fi -} - -function pyenv_executable_found() { - which pyenv > /dev/null 2>&1 - - return $? -} - -function checkout_specific_branch() { - git checkout -b rel-1.2.9 ${PYENV_REPOSITORY_RELEASE_CANDIDATE} -} - -function install_pyenv_build() { - PREFIX=${PYENV_REPOSITORY_LOCATION} ./install.sh -} - -function clone_pyenv_repository() { - if [ ! -d "$PYENV_REPOSITORY_LOCATION" ]; then - echo_step_title "Cloning the pyenv GitHub project located at $PYENV_GITHUB_LOCATION" - - git clone "$PYENV_GITHUB_LOCATION" "$PYENV_REPOSITORY_LOCATION" - THIS_DIRECTORY=`pwd` - cd "$PYENV_REPOSITORY_LOCATION" - checkout_specific_branch - cd plugins/python-build - install_pyenv_build - cd ${THIS_DIRECTORY} - exit_if_return_code_is_non_zero - else - echo_with_indentation " - pyenv git repository already cloned to $PYENV_REPOSITORY_LOCATION. Won't attempt to clone again." - fi -} - -function install_virtualenv() { - ${PYENV_BIN}/pip install virtualenv -} - -function export_pyenv_and_pyenv_repository_paths() { - export PATH="$PYENV_ROOT/bin:$PYENV_REPOSITORY_LOCATION/bin:$PATH" -} - -function verify_http_client_exists() { - if type curl &>/dev/null; then - return - elif type aria2c &>/dev/null; then - return - elif [[ "$(wget --version 2>/dev/null || true)" = "GNU Wget 1.1"[0-3]* ]]; then - echo_error_message "wget (>= 1.14) or curl (>= 7.18.1) is required to download and install Python." - exit 1 - elif [ -n "$(wget --version 2>/dev/null)" ]; then - return - else - echo_error_message "Could not find \`curl\`, \`wget\`, or \`aria2c\`. Please install one of these tools to continue Python installation" - exit 1 - fi -} - -function main() { - echo_step_title "Determining whether pyenv is already installed and in PATH" - - if pyenv_executable_found ; then - echo_with_indentation " - pyenv found in PATH. Won't clone pyenv git repository from GitHub" - else - echo_with_indentation " - pyenv was not found in PATH." - - echo_step_title "Determining whether pyenv should be cloned from GitHub" - clone_pyenv_repository - fi - - echo_step_title "Temporarily export necessary pyenv paths" - export_pyenv_and_pyenv_repository_paths - - echo_step_title "Checking whether Python can be downloaded (through curl, wget, or aria2c)" - verify_http_client_exists - - echo_step_title "Installing Python $PYTHON_VERSION. This step may take a few minutes" - install_python - - echo_step_title "Installing virtualenv using $PYENV_BIN/pip" - install_virtualenv -} -export print_path_export_instructions -export echo_with_indentation -main