From 0aaab179bef823ad6456a80b4a7edffeee60fc47 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 24 Oct 2016 17:06:59 +0200 Subject: [PATCH 1/9] Initial version of an install script. Currently supports Mac & Linux, including Bash & ZSH shells. Needs testing. --- bin/install.sh | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 bin/install.sh diff --git a/bin/install.sh b/bin/install.sh new file mode 100644 index 0000000..470c16f --- /dev/null +++ b/bin/install.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# Ensure PHP is installed +php -v > /dev/null 2>&1 +if [[ $? -ne 0 ]]; then + echo "PHP is not found, installation aborted!" + exit 1 +fi + +# Check if Composer is already globally available +composer -v > /dev/null 2>&1 + +# Ensure Composer is installed/updated +if [[ $? -ne 0 ]]; then + echo "*** Installing Composer ***" + + EXPECTED_SIGNATURE=$(wget https://composer.github.io/installer.sig -O - -q) + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") + + if [ "$EXPECTED_SIGNATURE" = "$ACTUAL_SIGNATURE" ] + then + php composer-setup.php --quiet --filename=composer + RESULT=$? + if [[ $? -eq 0 ]]; then + sudo mv composer /usr/local/bin/composer + RESULT=$? + fi + rm composer-setup.php + if [[ RESULT -ne 0 ]]; then + exit $RESULT + fi + else + >&2 echo 'ERROR: Invalid composer installer signature' + rm composer-setup.php + exit 1 + fi +else + echo "*** Updating Composer ***" + composer selfupdate > /dev/null 2>&1 + if [[ $? -ne 0 ]]; then + composer global update "composer/composer" + fi +fi + +echo "*** Updating shell profiles ***" +# Add Composer's Global Bin to ~/.profile path +if [[ ! -f "~/.profile" ]]; then + touch ~/.profile +fi +grep -q -F 'export COMPOSER_HOME="~/.composer"' ~/.profile || echo 'export COMPOSER_HOME="~/.composer"' >> ~/.profile +grep -q -F 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' ~/.profile || echo 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' >> ~/.profile + +# Source the .profile to pick up changes +. ~/.profile + +# Test if ZSH is installed +zsh --version > /dev/null 2>&1 +if [[ $? -eq 0 ]]; then + # Add Composer's Global Bin to ~/.zprofile path + if [[ ! -f "~/.zprofile" ]]; then + touch ~/.zprofile + fi + grep -q -F 'export COMPOSER_HOME="~/.composer"' ~/.zprofile || echo 'export COMPOSER_HOME="~/.composer"' >> ~/.zprofile + grep -q -F 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' ~/.zprofile || echo 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' >> ~/.zprofile + + # Source the .zprofile to pick up changes + . ~/.zprofile +fi + +# Ensure Dealerdirect PHP QA tools are installed globally +echo "*** Installing Dealerdirect PHP QA Tools ***" +composer global require "dealerdirect/qa-tools:@dev" + +echo "*** Updating Dealerdirect PHP QA Tools ***" +composer global update "dealerdirect/qa-tools:@dev" From 2640e93ed3c8e490d5dbbe17d6b44b7367d2c5c3 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 25 Oct 2016 11:08:07 +0200 Subject: [PATCH 2/9] Improved installer script based on feedback & shellcheck. --- bin/install.sh | 66 ++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/bin/install.sh b/bin/install.sh index 470c16f..403ce8b 100644 --- a/bin/install.sh +++ b/bin/install.sh @@ -1,71 +1,63 @@ #!/usr/bin/env bash +set -eu # Ensure PHP is installed -php -v > /dev/null 2>&1 -if [[ $? -ne 0 ]]; then +if ! command -v php > /dev/null 2>&1; then echo "PHP is not found, installation aborted!" exit 1 fi -# Check if Composer is already globally available -composer -v > /dev/null 2>&1 - # Ensure Composer is installed/updated -if [[ $? -ne 0 ]]; then +if ! command -v composer > /dev/null 2>&1; then echo "*** Installing Composer ***" - - EXPECTED_SIGNATURE=$(wget https://composer.github.io/installer.sig -O - -q) php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") - if [ "$EXPECTED_SIGNATURE" = "$ACTUAL_SIGNATURE" ] - then + if [ \ + "$(curl -S https://composer.github.io/installer.sig)" = \ + "$(php -r \"echo hash_file\('SHA384', 'composer-setup.php'\);\")" \ + ]; then php composer-setup.php --quiet --filename=composer - RESULT=$? - if [[ $? -eq 0 ]]; then - sudo mv composer /usr/local/bin/composer - RESULT=$? - fi + sudo mv composer /usr/local/bin/composer rm composer-setup.php - if [[ RESULT -ne 0 ]]; then - exit $RESULT - fi else >&2 echo 'ERROR: Invalid composer installer signature' rm composer-setup.php exit 1 fi -else - echo "*** Updating Composer ***" - composer selfupdate > /dev/null 2>&1 - if [[ $? -ne 0 ]]; then - composer global update "composer/composer" - fi fi echo "*** Updating shell profiles ***" # Add Composer's Global Bin to ~/.profile path -if [[ ! -f "~/.profile" ]]; then - touch ~/.profile +if [[ ! -f "$HOME/.profile" ]]; then + touch "$HOME/.profile" +fi +if grep -q -F "export COMPOSER_HOME=$HOME/.composer" "$HOME/.profile"; then + echo "export COMPOSER_HOME=$HOME/.composer" >> "$HOME/.profile" +fi +if grep -q -F "export PATH=$PATH:\$COMPOSER_HOME/vendor/bin" "$HOME/.profile"; then + echo "export PATH=$PATH:\$COMPOSER_HOME/vendor/bin" >> "$HOME/.profile" fi -grep -q -F 'export COMPOSER_HOME="~/.composer"' ~/.profile || echo 'export COMPOSER_HOME="~/.composer"' >> ~/.profile -grep -q -F 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' ~/.profile || echo 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' >> ~/.profile # Source the .profile to pick up changes -. ~/.profile +# shellcheck source=/dev/null +source "$HOME/.profile" # Test if ZSH is installed -zsh --version > /dev/null 2>&1 -if [[ $? -eq 0 ]]; then +if command -v zsh > /dev/null 2>&1; then # Add Composer's Global Bin to ~/.zprofile path - if [[ ! -f "~/.zprofile" ]]; then - touch ~/.zprofile + if [[ ! -f "$HOME/.zprofile" ]]; then + touch "$HOME/.zprofile" + fi + if grep -q -F "export COMPOSER_HOME=$HOME/.composer" "$HOME/.zprofile"; then + echo "export COMPOSER_HOME=$HOME/.composer" >> "$HOME/.zprofile" + fi + if grep -q -F "export PATH=$PATH:$COMPOSER_HOME/vendor/bin" "$HOME/.zprofile"; then + echo "export PATH=$PATH:$COMPOSER_HOME/vendor/bin" >> "$HOME/.zprofile" fi - grep -q -F 'export COMPOSER_HOME="~/.composer"' ~/.zprofile || echo 'export COMPOSER_HOME="~/.composer"' >> ~/.zprofile - grep -q -F 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' ~/.zprofile || echo 'export PATH=$PATH:$COMPOSER_HOME/vendor/bin' >> ~/.zprofile # Source the .zprofile to pick up changes - . ~/.zprofile + # shellcheck source=/dev/null + source "$HOME/.zprofile" fi # Ensure Dealerdirect PHP QA tools are installed globally From 124dad5de27a437c29dabbe9a2488ee1f1e1640d Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 25 Oct 2016 15:45:53 +0200 Subject: [PATCH 3/9] Improved install.sh to handle install vs update of the dealerdirect/qa-tools package. --- bin/install.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bin/install.sh b/bin/install.sh index 403ce8b..a982139 100644 --- a/bin/install.sh +++ b/bin/install.sh @@ -60,9 +60,15 @@ if command -v zsh > /dev/null 2>&1; then source "$HOME/.zprofile" fi -# Ensure Dealerdirect PHP QA tools are installed globally -echo "*** Installing Dealerdirect PHP QA Tools ***" -composer global require "dealerdirect/qa-tools:@dev" - -echo "*** Updating Dealerdirect PHP QA Tools ***" -composer global update "dealerdirect/qa-tools:@dev" +# Install/Update Dealerdirect QA tools +if ! grep -q -F "dealerdirect/qa-tools" "$HOME/.composer/composer.json" > /dev/null 2>&1; then + echo "*** Installing Composer Prestissimo in order to speed up next steps ***" + composer global require "hirak/prestissimo:^0.3" + echo "*** Installing Dealerdirect PHP QA Tools ***" + composer global require "dealerdirect/qa-tools:@dev" + echo "*** Removing local Prestissimo dependency ***" + composer global remove "hirak/prestissimo" +else + echo "*** Updating Dealerdirect PHP QA Tools ***" + composer global update "dealerdirect/qa-tools:@dev" +fi From ac7a81ee65bde946e195d9c7955aab799b98b438 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 25 Oct 2016 16:15:47 +0200 Subject: [PATCH 4/9] Updated documentation with installation instructions --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index 093bf93..9a6f85e 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,48 @@ The following packages are suggested: [phpDox]: http://phpdox.de [Sami]: https://github.com/FriendsOfPHP/sami +## Usage + +This is a simple metapackage, but still can be used in different ways. + +#### Global install + +This is by far the easiest and most convenient method. Simply having all the tools available system wide. + +The following script will install a system wide Composer for you, including the QA tools. + +```bash +bash <(curl -S https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh) +``` + +If you already have a global Composer setup, you can execute this to include the tools. + +```bash +composer global require "dealerdirect/qa-tools" +``` + +#### Project install + +The other option is to install this on a per project basis. + +```bash +composer require --dev "dealerdirect/qa-tools" +``` + +Or modify your `composer.json` to include `dealerdirect/qa-tools` in the `require-dev` sections. + +```json +{ + "name": "acme/my-project", + "require": { + "** your requirements **": "*" + }, + "require-dev": { + "dealerdirect/qa-tools": "*" + } +} +``` + ## Contributing This is an active open-source project. We are always open to people who want to use the code or contribute to it. From 5d549c62cd415e75d5bdebc9f607aa3593961002 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 27 Oct 2016 12:20:30 +0200 Subject: [PATCH 5/9] Improved installer script and documentation based on feedback in pr #3 --- README.md | 48 +++++-- bin/install.sh | 370 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 346 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 69d3dcd..ccf7ba1 100644 --- a/README.md +++ b/README.md @@ -85,11 +85,25 @@ The following packages are suggested: ## Usage -This is a simple metapackage, but still can be used in different ways. +This is a simple metapackage which can be used in two different ways; globally installed or on a per project basis. -#### Global install +Both methods have their pros (+) and cons (-). -This is by far the easiest and most convenient method. Simply having all the tools available system wide. +**Global installation**: +* \+ All tools are present anywhere on your system +* \+ Can be used on any codebase, even the ones that don't use Composer. +* \- You'll have to update manually, since it's not a project, versioning is not managed. + +*Per project installation*: +* \+ Versioning (update/installation) is provided in the project +* \- Tools not available system wide. You'll need to execute them from a specific path. + +These methods are not mutual exclusive. You can have your global installed version, which can be used anywhere, but +still use the one provided in a project. + +## Installation + +### Global installation The following script will install a system wide Composer for you, including the QA tools. @@ -97,27 +111,43 @@ The following script will install a system wide Composer for you, including the bash <(curl -S https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh) ``` -If you already have a global Composer setup, you can execute this to include the tools. +That's it. This can be put in any instructions, such as a README or someone's blog, since the logic is in the shell +script. Provided you download the script using https, the file has standard levels of authentication and encryption +protecting it from manipulation. + +This is obviously a shell script, if you're really concerned about the argument that it may contain nefarious +activities within, you can easily review it before you run it. + +```bash +curl -o https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh +less install.sh +bash instal.sh +``` + +If you already have a global Composer setup, you could include the tools manually, without the need for running +the shell script above. ```bash -composer global require "dealerdirect/qa-tools" +composer global require "dealerdirect/qa-tools:*" ``` -#### Project install +#### Per project installation The other option is to install this on a per project basis. +Using Composer (preferred method): + ```bash -composer require --dev "dealerdirect/qa-tools" +composer require --dev "dealerdirect/qa-tools:*" ``` -Or modify your `composer.json` to include `dealerdirect/qa-tools` in the `require-dev` sections. +Or modify your `composer.json` to include `dealerdirect/qa-tools` in the `require-dev` sections: ```json { "name": "acme/my-project", "require": { - "** your requirements **": "*" + "…": "*" }, "require-dev": { "dealerdirect/qa-tools": "*" diff --git a/bin/install.sh b/bin/install.sh index a982139..e93346a 100644 --- a/bin/install.sh +++ b/bin/install.sh @@ -1,74 +1,318 @@ #!/usr/bin/env bash -set -eu +# ============================================================================== +# +# Dealerdirect PHP QA Tools Installer +# +# Installs Composer and the Dealerdirect PHP Quality Assurance tools +# globally on your system. +# +# ============================================================================== +# MIT License +# +# Copyright (c) 2016 Dealerdirect B.V. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# ============================================================================== +set -o errexit # Exit script when a command exits with non-zero status +set -o nounset # Exit script on use of an undefined variable +set -o pipefail # Return exit status of the last command in the pipe that failed -# Ensure PHP is installed -if ! command -v php > /dev/null 2>&1; then - echo "PHP is not found, installation aborted!" - exit 1 -fi +# ============================================================================== +# GLOBALS +# ============================================================================== +readonly EX_OK=0 # Successful termination +readonly EX_ROOT=3 # Running as root +readonly EX_PHP_NOT_FOUND=4 # PHP was not found +readonly EX_GIT_NOT_FOUND=5 # GIT not found +readonly EX_CURL_NOT_FOUND=6 # curl not found +readonly EX_NET_ERR=7 # Something went wrong during a file download +readonly EX_SIG_MISMATCH=8 # Composer installer signature mismatch +readonly EX_SETUP_ERR=9 # Composer setup failure -# Ensure Composer is installed/updated -if ! command -v composer > /dev/null 2>&1; then - echo "*** Installing Composer ***" - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +# Temporary directory for storing the Composer setup script +readonly COMPOSER_TMPDIR=$(mktemp -d "/tmp/composer.XXXXXXXXXXXX") + +# ============================================================================== +# UTILITY +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Displays a status message +# Globals: +# None +# Arguments: +# $* Status message to display +# Returns: +# None +# ------------------------------------------------------------------------------ +display_status_message() { + local status=$* + + echo + echo "-----> $*" + echo +} + +# ------------------------------------------------------------------------------ +# Displays a notice +# Globals: +# None +# Arguments: +# $* Notice message to display +# Returns: +# None +# ------------------------------------------------------------------------------ +display_notice_message() { + local status=$* + + echo + echo "NOTICE: $*" + echo +} + +# ------------------------------------------------------------------------------ +# Displays a error message and is able to terminate te script execution +# Globals: +# None +# Arguments: +# $1 Error message +# $2 Exitcode, script will continue execution when omitted +# Returns: +# None +# ------------------------------------------------------------------------------ +display_error_message() { + local status=$1 + local exitcode=${2:-0} + + echo >&2 + echo " ! ERROR: $status" >&2 + echo >&2 + + if [[ $exitcode -ne 0 ]]; then + exit "$exitcode" + fi +} + +# ============================================================================== +# SCRIPT LOGIC +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Check if required tools for this script are installed. +# Globals: +# EX_CURL_NOT_FOUND +# EX_GIT_NOT_FOUND +# EX_PHP_NOT_FOUND +# EX_ROOT +# UID +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +check_runtime_requirements() { + if [[ "$UID" -eq 0 ]]; then + display_error_message 'This script must NOT be run as root' $EX_ROOT + fi + type php > /dev/null 2>&1 || display_error_message \ + 'PHP is not found, installation aborted!' $EX_PHP_NOT_FOUND + type git > /dev/null 2>&1 || display_error_message \ + 'GIT is not found, installation aborted!' $EX_GIT_NOT_FOUND + type curl > /dev/null 2>&1 || display_error_message \ + 'curl is not found, installation aborted!' $EX_CURL_NOT_FOUND +} + +# ------------------------------------------------------------------------------ +# Install composer on this system +# Globals: +# COMPOSER_TMPDIR +# EX_SETUP_ERR +# EX_SIG_MISMATCH +# EX_NET_ERR +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +install_composer() { + local composer_filename="composer" + local composer_setup="$COMPOSER_TMPDIR/composer-setup.php" + local composer_temp="$COMPOSER_TMPDIR/$composer_filename" + local composer_dest="/usr/local/bin/$composer_filename" + + display_status_message 'Downloading Composer setup' + command curl -o "$composer_setup" 'https://getcomposer.org/installer' || + display_error_message 'Failed downloading Composer installer' $EX_NET_ERR + + display_status_message 'Checking Composer setup signature' if [ \ - "$(curl -S https://composer.github.io/installer.sig)" = \ - "$(php -r \"echo hash_file\('SHA384', 'composer-setup.php'\);\")" \ + "$(command curl -S https://composer.github.io/installer.sig)" != \ + "$(command php -r "echo hash_file(\"SHA384\", \"$composer_setup\");")" \ ]; then - php composer-setup.php --quiet --filename=composer - sudo mv composer /usr/local/bin/composer - rm composer-setup.php - else - >&2 echo 'ERROR: Invalid composer installer signature' - rm composer-setup.php - exit 1 + display_error_message \ + 'Invalid composer installer signature' $EX_SIG_MISMATCH + fi + + display_status_message 'Running Composer setup' + command php "$composer_setup" --quiet --filename="$composer_filename" \ + --install-dir="$COMPOSER_TMPDIR" || display_error_message \ + 'Error occured while running Composer setup' $EX_SETUP_ERR + + display_notice_message \ + 'Installing Composer globally. Administrator privileges will be required...' + sudo mv "$composer_temp" "$composer_dest" || + display_error_message \ + "Failed moving Composer to $composer_dest" $EX_SETUP_ERR + + display_status_message 'Composer has been installed.' +} + +# ------------------------------------------------------------------------------ +# Updates a shell profile with extra environment variables. +# Globals: +# COMPOSER_TMPDIR +# HOME +# Arguments: +# $1 Profile file to update +# Returns: +# None +# ------------------------------------------------------------------------------ +update_profile() { + local profile="$HOME/$1" + + display_status_message "Updating profile file '$profile'" + + if [[ ! -f "$profile" ]]; then + command touch "$profile" fi -fi - -echo "*** Updating shell profiles ***" -# Add Composer's Global Bin to ~/.profile path -if [[ ! -f "$HOME/.profile" ]]; then - touch "$HOME/.profile" -fi -if grep -q -F "export COMPOSER_HOME=$HOME/.composer" "$HOME/.profile"; then - echo "export COMPOSER_HOME=$HOME/.composer" >> "$HOME/.profile" -fi -if grep -q -F "export PATH=$PATH:\$COMPOSER_HOME/vendor/bin" "$HOME/.profile"; then - echo "export PATH=$PATH:\$COMPOSER_HOME/vendor/bin" >> "$HOME/.profile" -fi - -# Source the .profile to pick up changes -# shellcheck source=/dev/null -source "$HOME/.profile" - -# Test if ZSH is installed -if command -v zsh > /dev/null 2>&1; then - # Add Composer's Global Bin to ~/.zprofile path - if [[ ! -f "$HOME/.zprofile" ]]; then - touch "$HOME/.zprofile" + + update_profile_export "COMPOSER_HOME" "$HOME/.composer" "$profile" + update_profile_export "PATH" "\$PATH:\$COMPOSER_HOME/vendor/bin" "$profile" +} + +# ------------------------------------------------------------------------------ +# Helper function for ensuring an enviroment variable is exported profile file +# Globals: +# None +# Arguments: +# $1 Enviroment variable name to export +# $2 Value of enviroment variable to export +# $3 Profile file to update +# Returns: +# None +# ------------------------------------------------------------------------------ +update_profile_export() { + local export_line="export ${1}=${2}" + local profile=$3 + + if ! grep -q -F "${export_line}" "$profile"; then + echo "$export_line" >> "$profile" fi - if grep -q -F "export COMPOSER_HOME=$HOME/.composer" "$HOME/.zprofile"; then - echo "export COMPOSER_HOME=$HOME/.composer" >> "$HOME/.zprofile" +} + +# ------------------------------------------------------------------------------ +# Uses Composer to install the QA tools +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +install_qa_tools() { + display_status_message \ + 'Installing Composer Prestissimo in order to speed up next steps' + command composer global require 'hirak/prestissimo:^0.3' + + display_status_message 'Installing Dealerdirect PHP QA Tools' + command composer global require 'dealerdirect/qa-tools:*' + + display_status_message 'Removing local Prestissimo dependency' + command composer global remove 'hirak/prestissimo' +} + +# ------------------------------------------------------------------------------ +# Runs Composer updating the QA tools +# Globals: +# None +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +update_qa_tools() { + display_status_message 'Updating Dealerdirect PHP QA Tools' + command composer global update 'dealerdirect/qa-tools' +} + +# ------------------------------------------------------------------------------ +# Cleanup function after execution is of the script is stopped. (trap) +# Globals: +# COMPOSER_TMPDIR +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +cleanup() { + command rm -f -r "$COMPOSER_TMPDIR" +} + +# ============================================================================== +# RUN LOGIC +# ------------------------------------------------------------------------------ +# Globals: +# EX_OK +# HOME +# SHELL +# Arguments: +# None +# Returns: +# None +# ------------------------------------------------------------------------------ +main() { + trap cleanup ERR + trap cleanup EXIT + + check_runtime_requirements + type composer > /dev/null 2>&1 || install_composer + + update_profile '.profile' + if [[ "$(basename "$SHELL")" = 'zsh' ]]; then + update_profile '.zprofile' fi - if grep -q -F "export PATH=$PATH:$COMPOSER_HOME/vendor/bin" "$HOME/.zprofile"; then - echo "export PATH=$PATH:$COMPOSER_HOME/vendor/bin" >> "$HOME/.zprofile" + + if ! grep -q -F "dealerdirect/qa-tools" \ + "$HOME/.composer/composer.json" > /dev/null 2>&1; + then + install_qa_tools + else + update_qa_tools fi - # Source the .zprofile to pick up changes - # shellcheck source=/dev/null - source "$HOME/.zprofile" -fi - -# Install/Update Dealerdirect QA tools -if ! grep -q -F "dealerdirect/qa-tools" "$HOME/.composer/composer.json" > /dev/null 2>&1; then - echo "*** Installing Composer Prestissimo in order to speed up next steps ***" - composer global require "hirak/prestissimo:^0.3" - echo "*** Installing Dealerdirect PHP QA Tools ***" - composer global require "dealerdirect/qa-tools:@dev" - echo "*** Removing local Prestissimo dependency ***" - composer global remove "hirak/prestissimo" -else - echo "*** Updating Dealerdirect PHP QA Tools ***" - composer global update "dealerdirect/qa-tools:@dev" -fi + display_status_message 'Installation completed.' + + display_notice_message \ + 'Your shell enviroment might have been changed.' \ + 'Please restart your terminal session.' + + exit $EX_OK +} +main From 31291ef5100f779c07b243a73675646f824540eb Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 27 Oct 2016 13:42:03 +0200 Subject: [PATCH 6/9] Updated .editorconfig --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index 3a27d66..b8176fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,9 @@ trim_trailing_whitespace = true ident_size = 2 trim_trailing_whitespace = false +[*.sh] +ident_size = 2 + [*.json] ident_size = 2 From 69ca2abdaf0730e938e62e1c0ca1e7e04eb38e65 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 27 Oct 2016 13:43:55 +0200 Subject: [PATCH 7/9] Removed root check from install script. While installing as root is not recommended, forbidding it could give problems in CI builds (e.g. TravisCI & Bitbucket Pipelines). --- bin/install.sh | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/bin/install.sh b/bin/install.sh index e93346a..94abdf9 100644 --- a/bin/install.sh +++ b/bin/install.sh @@ -37,13 +37,12 @@ set -o pipefail # Return exit status of the last command in the pipe that failed # GLOBALS # ============================================================================== readonly EX_OK=0 # Successful termination -readonly EX_ROOT=3 # Running as root -readonly EX_PHP_NOT_FOUND=4 # PHP was not found -readonly EX_GIT_NOT_FOUND=5 # GIT not found -readonly EX_CURL_NOT_FOUND=6 # curl not found -readonly EX_NET_ERR=7 # Something went wrong during a file download -readonly EX_SIG_MISMATCH=8 # Composer installer signature mismatch -readonly EX_SETUP_ERR=9 # Composer setup failure +readonly EX_PHP_NOT_FOUND=3 # PHP was not found +readonly EX_GIT_NOT_FOUND=4 # GIT not found +readonly EX_CURL_NOT_FOUND=5 # curl not found +readonly EX_NET_ERR=6 # Something went wrong during a file download +readonly EX_SIG_MISMATCH=7 # Composer installer signature mismatch +readonly EX_SETUP_ERR=8 # Composer setup failure # Temporary directory for storing the Composer setup script readonly COMPOSER_TMPDIR=$(mktemp -d "/tmp/composer.XXXXXXXXXXXX") @@ -119,7 +118,6 @@ display_error_message() { # EX_CURL_NOT_FOUND # EX_GIT_NOT_FOUND # EX_PHP_NOT_FOUND -# EX_ROOT # UID # Arguments: # None @@ -127,9 +125,6 @@ display_error_message() { # None # ------------------------------------------------------------------------------ check_runtime_requirements() { - if [[ "$UID" -eq 0 ]]; then - display_error_message 'This script must NOT be run as root' $EX_ROOT - fi type php > /dev/null 2>&1 || display_error_message \ 'PHP is not found, installation aborted!' $EX_PHP_NOT_FOUND type git > /dev/null 2>&1 || display_error_message \ From 809ce4c2d49db35fb935c4b951c78321b83081a6 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 27 Oct 2016 14:24:39 +0200 Subject: [PATCH 8/9] Added GPG signed installer & documentation. --- README.md | 15 +++++++++++++-- bin/install.sh.sig | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 bin/install.sh.sig diff --git a/README.md b/README.md index ccf7ba1..987b19c 100644 --- a/README.md +++ b/README.md @@ -113,17 +113,28 @@ bash <(curl -S https://raw.githubusercontent.com/DealerDirect/php-qa-tools/maste That's it. This can be put in any instructions, such as a README or someone's blog, since the logic is in the shell script. Provided you download the script using https, the file has standard levels of authentication and encryption -protecting it from manipulation. +protecting it from manipulation. We also sign the install with a GPG key, this way you can check if the downloaded +releases signature matches the public key of Dealerdirect. + +```bash +gpg --keyserver hkp://keys.gnupg.net --recv-keys C4133165DF5EB4BAEABDADCACF1E7823C5339B59 +curl -O https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh +curl -O https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh.sig +gpg --verify install.sh.sig +bash install.sh +``` This is obviously a shell script, if you're really concerned about the argument that it may contain nefarious activities within, you can easily review it before you run it. ```bash -curl -o https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh +curl -O https://raw.githubusercontent.com/DealerDirect/php-qa-tools/master/bin/install.sh less install.sh bash instal.sh ``` + + If you already have a global Composer setup, you could include the tools manually, without the need for running the shell script above. diff --git a/bin/install.sh.sig b/bin/install.sh.sig new file mode 100644 index 0000000..b7250d4 --- /dev/null +++ b/bin/install.sh.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABCgAGBQJYEe4zAAoJELY9nlxX4qkVWOgQAJ3X9wfOUgkBmXOzdNby/8sF +L75nfahYKHgNpK0uoLDp18w3b9QhbNLDRZTAMpKKtykD8rXZ6zG/2GXvc9XObAf+ +QsTs4fEOsACy/PFHmHpnW2/L+loM7bRanRRWgR30NFQP2sj0DPRBQwNFK0321dem +Cpvp6DKDU+kseAj6yP2qurAmDp8YzwG0qYN+n3dHhhl8XRd6b+hZFcHzqKTLGGpv +tP13jPprOTC0fNDfGYAXiZrjbiC4f6OvcRZid/Kp8dG/H3aGO+JsDFiRqi4KlBYq +fz8XrHKh0LztYBgX3x47qRPOeVpeg1N7aNcpJXnIpwP7vlwBidT50i7Vw354yq7n +HlG0W67W4t3PIE+KoT5bpX3RiIwkyTl9hMVYny2ERmGdeGwiu6OBJb7MtDejElw7 +O6UehVgUqZaJaWV/+luQ/OMsJXHEgFVd64BiXEJT+YUpg/s9zFhmNXH8lKkYxuZz +Plx46fIY3PCC1oQaYQ/olQtBIiBP4J8IZcR4ZuN+z5ihuR+51yzHLMGhaiRnzIku +TZfKUkuGdhe4YHng4NIb1weOXzoRaMgYzQkhwCd3zWBli3yhX5atvEi+KD0Wq56Z +shFO5SjSq6Lgmfv8V6SgAy+okxCN9C1KIyoJTEWh3ciUMuzeG2ehqEiMXs6CSHv8 +UuSQbq19lh2yFxKYkCmE +=QjAG +-----END PGP SIGNATURE----- From 308960083e270d011e8900390dafac07d0ce7ff2 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Thu, 27 Oct 2016 14:51:27 +0200 Subject: [PATCH 9/9] Documentation update, removed version constrain from installation instructions, in case of require-dev --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 987b19c..449f616 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ The other option is to install this on a per project basis. Using Composer (preferred method): ```bash -composer require --dev "dealerdirect/qa-tools:*" +composer require --dev "dealerdirect/qa-tools" ``` Or modify your `composer.json` to include `dealerdirect/qa-tools` in the `require-dev` sections: