Skip to content

Instantly share code, notes, and snippets.

@Potherca
Last active January 26, 2020 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Potherca/49bdf3fb36d2c03c643c28084d74e4a7 to your computer and use it in GitHub Desktop.
Save Potherca/49bdf3fb36d2c03c643c28084d74e4a7 to your computer and use it in GitHub Desktop.
Automated reproduction of all scenarios related to Dealerdirect/phpcodesniffer-composer-installer issues #103

Introduction

This gist contains a BASH script that runs through all 16 scenarios related to Dealerdirect/phpcodesniffer-composer-installer issues #103.

For v0.6.0 of phpcodesniffer-composer-installer, three scenarios fail.

This is the scenario reported in the issue, and the scenarios described by @jrfnl:

❌ 09. Going from no-dev to uninstall with Codesniffer Package in require and Installer Plugin in require
❌ 16. Going from dev to no-dev with Codesniffer Package in require-dev and Installer Plugin in require-dev
❌ 21. Going from dev to uninstall with Codesniffer Package in require and Installer Plugin in require

Screenshot of test results

Usage example

The test scenarios can be run like this:

bash ./reproduce_issue_103.sh /tmp

The test scenarios can also be run with a development version of the phpcodesniffer-composer-installer plugin. In order to do so, pass the path to plugin as the second parameter:

bash ./reproduce_issue_103.sh /tmp ./phpcodesniffer-composer-installer

Factors

The following factors are involved in the scenarios:

  • PHP Codesniffer Package (A)
  • PHP Codesniffer Composer Installer Plugin (B)
  • require / no-dev (I)
  • require-dev / dev (J)
  • Manual Uninstall (K)

Variations

The Package and Plugin are present in the scenarios in the following variations:

  1. PHP Codesniffer Package (A) in Require (I) and PHP Codesniffer Composer Installer Plugin (B) in Require (I) (A+I/B+I)
  2. PHP Codesniffer Package (A) in Require (I) and PHP Codesniffer Composer Installer Plugin (B) in Require-dev (J) (A+I/B+J)
  3. PHP Codesniffer Package (A) in Require-dev (J) and PHP Codesniffer Composer Installer Plugin (B) in Require (I) (A+J/B+I)
  4. PHP Codesniffer Package (A) in Require-dev (J) and PHP Codesniffer Composer Installer Plugin (B) in Require-dev (J) (A+J/B+J)

Flow

The scenarios go through the following flows:

  1. Going from no-dev (I) to no-dev (I) (I->I)
  2. Going from no-dev (I) to dev (J) (I->J)
  3. Going from no-dev (I) to uninstall (K) (I->K)
  4. Going from dev (J) to no-dev (I) (J->I)
  5. Going from dev (J) to dev (J) (J->J)
  6. Going from dev (J) to uninstall (K) (J->K)

Scenarios

The above factors, in their various variations and flows, give us the following 24 possible scenarios:

  1. (I->I)
    1. (A+I/B+I) = I:I:I:I
    2. (A+I/B+J) = I:I:I:J
    3. (A+J/B+I) = I:I:J:I
    4. (A+J/B+J) = I:I:J:J
  2. (I->J)
    1. (A+I/B+I) = I:J:I:I
    2. (A+I/B+J) = I:J:I:J
    3. (A+J/B+I) = I:J:J:I
    4. (A+J/B+J) = I:J:J:J
  3. (I->K)
    1. (A+I/B+I) = I:K:I:I
    2. (A+I/B+J) = I:k:I:J
    3. (A+J/B+I) = I:K:J:I
    4. (A+J/B+J) = I:K:J:J
  4. (J->I)
    1. (A+I/B+I) = J:I:I:I
    2. (A+I/B+J) = J:I:I:J
    3. (A+J/B+I) = J:I:J:I
    4. (A+J/B+J) = J:I:J:J
  5. (J->J)
    1. (A+I/B+I) = J:J:I:I
    2. (A+I/B+J) = J:J:I:J
    3. (A+J/B+I) = J:J:J:I
    4. (A+J/B+J) = J:J:J:J
  6. (J->K)
    1. (A+I/B+I) = J:K:I:I
    2. (A+I/B+J) = J:k:I:J
    3. (A+J/B+I) = J:K:J:I
    4. (A+J/B+J) = j:K:J:J

Example output

For v0.6.0 of phpcodesniffer-composer-installer, running the scenarios gives the following output:

✔️ 01. Going from no-dev to no-dev with Codesniffer Package in require and Installer Plugin in require
✔️ 02. Going from no-dev to no-dev with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 03. Going from no-dev to no-dev with Codesniffer Package in require-dev and Installer Plugin in require
✔️ 04. Going from no-dev to no-dev with Codesniffer Package in require-dev and Installer Plugin in require-dev
✔️ 05. Going from no-dev to dev with Codesniffer Package in require and Installer Plugin in require
✔️ 06. Going from no-dev to dev with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 07. Going from no-dev to dev with Codesniffer Package in require-dev and Installer Plugin in require
✔️ 08. Going from no-dev to dev with Codesniffer Package in require-dev and Installer Plugin in require-dev
❌ 09. Going from no-dev to uninstall with Codesniffer Package in require and Installer Plugin in require
✔️ 10. Going from no-dev to uninstall with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 11. Going from no-dev to uninstall with Codesniffer Package in require-dev and Installer Plugin in require
✔️ 12. Going from no-dev to uninstall with Codesniffer Package in require-dev and Installer Plugin in require-dev
✔️ 13. Going from dev to no-dev with Codesniffer Package in require and Installer Plugin in require
✔️ 14. Going from dev to no-dev with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 15. Going from dev to no-dev with Codesniffer Package in require-dev and Installer Plugin in require
❌ 16. Going from dev to no-dev with Codesniffer Package in require-dev and Installer Plugin in require-dev
✔️ 17. Going from dev to dev with Codesniffer Package in require and Installer Plugin in require
✔️ 18. Going from dev to dev with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 19. Going from dev to dev with Codesniffer Package in require-dev and Installer Plugin in require
✔️ 20. Going from dev to dev with Codesniffer Package in require-dev and Installer Plugin in require-dev
❌ 21. Going from dev to uninstall with Codesniffer Package in require and Installer Plugin in require
✔️ 22. Going from dev to uninstall with Codesniffer Package in require and Installer Plugin in require-dev
✔️ 23. Going from dev to uninstall with Codesniffer Package in require-dev and Installer Plugin in require
✔️ 24. Going from dev to uninstall with Codesniffer Package in require-dev and Installer Plugin in require-dev
       [ END ]
 ❌ Failure
#!/usr/bin/env bash
set -o errexit -o errtrace -o nounset -o pipefail
reproduce_issue_103() {
local -r sDirectoryParameter="${1?One parameter required: <directory>}"
local -r sDirectory="$(realpath "${sDirectoryParameter}")"
local -i iExitCode=0
local -r -a aScenarios=(
'no-dev:no-dev:require:require'
'no-dev:no-dev:require:require-dev'
'no-dev:no-dev:require-dev:require'
'no-dev:no-dev:require-dev:require-dev'
'no-dev:dev:require:require'
'no-dev:dev:require:require-dev'
'no-dev:dev:require-dev:require'
'no-dev:dev:require-dev:require-dev'
'dev:no-dev:require:require'
'dev:no-dev:require:require-dev'
'dev:no-dev:require-dev:require'
'dev:no-dev:require-dev:require-dev'
'dev:dev:require:require'
'dev:dev:require:require-dev'
'dev:dev:require-dev:require'
'dev:dev:require-dev:require-dev'
)
cleanup() {
if [[ -n ${sDirectory:-} ]];then
rm -rdf "${sDirectory}/vendor/" "${sDirectory}/composer.json" "${sDirectory}/composer.lock"
fi
}
composer_init() {
local -r sIssueNumber=103
local -r sPackageName="$(basename "${sDirectory}")"
composer init \
--author 'Ben Peachey <potherca@gmail.com>' \
--description "Full reproduction scenario for 'dealerdirect/phpcodesniffer-composer-installer' issue ${sIssueNumber}" \
--license 'GPL-3.0-or-later' \
--name "potherca/${sPackageName}" \
--no-interaction \
--repository '{ "type": "path", "url": "'"$(dirname "${sDirectory}")"'/phpcodesniffer-composer-installer", "options": { "symlink": false } }' \
--type 'project'
composer config 'sort-packages' 'true'
}
if [[ -d "${sDirectory}" ]];then
trap cleanup EXIT INT TERM
local -i iCounter=0
local sResult
local sFrom
local sTo
local sPackage
local sPlugin
local sScenario
pushd "${sDirectory}" > /dev/null
for sScenario in ${aScenarios[@]}; do
iCounter=$((iCounter+1))
sCounterText="$(printf "%02d" "${iCounter}")"
local IFS=:
read sFrom sTo sPackage sPlugin <<< "${sScenario}"
sScenarioText="Going from ${sFrom} to ${sTo} with Codesniffer Package in ${sPackage} and Installer Plugin in ${sPlugin}"
echo " ${sCounterText}. [START] ${sScenarioText}"
composer_init
echo -en "\r [. ] Require Package as ${sPackage} "
if [[ "${sPackage}" = 'require' ]];then
composer require --quiet --ignore-platform-reqs --no-update 'squizlabs/php_codesniffer'
else
composer require --quiet --ignore-platform-reqs --no-update --dev 'squizlabs/php_codesniffer'
fi
echo -en "\r [.. ] Require Plugin as ${sPlugin} "
if [[ "${sPlugin}" = 'require' ]];then
composer require --quiet --ignore-platform-reqs --no-update 'dealerdirect/phpcodesniffer-composer-installer'
else
composer require --quiet --ignore-platform-reqs --no-update --dev 'dealerdirect/phpcodesniffer-composer-installer'
fi
echo -en "\r [... ] Install ${sFrom} "
if [[ "${sFrom}" = 'no-dev' ]];then
composer install --quiet --ignore-platform-reqs --no-interaction --no-dev
else
composer install --quiet --ignore-platform-reqs --no-interaction
fi
sResult='✔️'
echo -en "\r [.... ] Install ${sTo} "
if [[ "${sTo}" = 'no-dev' ]];then
composer install --quiet --ignore-platform-reqs --no-interaction --no-dev || {
sResult='❌'
iExitCode=1
}
else
composer install --quiet --ignore-platform-reqs --no-interaction || {
sResult='❌'
iExitCode=1
}
fi
echo -en "\r [.....] Remove folders/files"
cleanup
echo -en "\r [ END ] "
echo -e "\e[1A\r${sResult} ${sCounterText}. ${sScenarioText} "
done
if [[ "${iExitCode}" = 0 ]];then
echo -e "\n ✔ Success"
else
echo -e "\n ❌ Failure"
fi
popd > /dev/null
else
echo "Given directory '${sDirectoryParameter}' does not exist"
iExitCode=65
fi
exit "${iExitCode}"
}
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then
export -f reproduce_issue_103
else
reproduce_issue_103 "${@}"
exit $?
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment