--- /dev/null
+#!/bin/bash
+
+SELF_DIRNAME="`dirname -- "$0"`"
+
+# The first argument is always the scenario name. Options come after.
+SCENARIO="$1"
+shift
+
+#
+# This script is typically called after `composer update` from a
+# "post-update-cmd" in the "scripts" section of composer.json.
+#
+
+# Defaults
+PLATFORM_PHP="--unset"
+STABILITY="stable"
+CREATE_LOCKFILE=true
+AUTOLOAD_DIRECTORIES="src tests"
+REMOVALS=
+REQUIREMENTS=
+BASE=..
+
+echo
+echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
+echo "::"
+echo ":: Create scenario ${SCENARIO}"
+echo "::"
+echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
+echo
+
+while [ $# -gt 0 ] ; do
+
+ option="$1"
+ shift
+
+ case "$option" in
+ --unset-platform-php)
+ PLATFORM_PHP="--unset"
+ shift
+ ;;
+
+ --platform-php)
+ PLATFORM_PHP="$1"
+ shift
+ ;;
+
+ --stability)
+ STABILITY="$1"
+ shift
+ ;;
+
+ --create-lockfile)
+ CREATE_LOCKFILE=true
+ ;;
+
+ --no-lockfile)
+ CREATE_LOCKFILE=false
+ ;;
+
+ --autoload-dir)
+ autoload_dir="$1"
+ shift
+ AUTOLOAD_DIRECTORIES="${AUTOLOAD_DIRECTORIES} ${autoload_dir}"
+ ;;
+
+ --remove)
+ project_to_remove="$1"
+ shift
+ REMOVALS="${REMOVALS} ${project_to_remove}"
+ ;;
+
+ --keep)
+ keep_pattern="$1"
+ shift
+ projects_to_remove="$(composer info --direct | cut -f 1 -d ' ' | grep -v $keep_pattern)"
+ REMOVALS="${REMOVALS} ${projects_to_remove}"
+ ;;
+
+ --base)
+ BASE="$1"
+ shift
+ ;;
+
+ -*)
+ echo "Unknown option $option"
+ exit 1;
+ ;;
+
+ *)
+ REQUIREMENTS="${REQUIREMENTS} ${option}"
+ ;;
+ esac
+done
+
+set -ex
+
+original_name=scenarios
+recommended_name=".scenarios.lock"
+
+scenarios_dir="$original_name"
+if [ -d "$recommended_name" ] ; then
+ scenarios_dir="$recommended_name"
+fi
+
+# Create the scenario directory, and start with a fresh composer.json file.
+dir="$scenarios_dir/${SCENARIO}"
+mkdir -p $dir
+cp $scenarios_dir/$BASE/composer.json $dir
+
+# Then set our own platform php version if applicable (otherwise unset it)
+[[ -z "${PLATFORM_PHP}" ]] || composer -n --working-dir=$dir config platform.php "${PLATFORM_PHP}"
+
+# Set an appropriate minimum stability for this version of Symfony
+composer -n --working-dir=$dir config minimum-stability "${STABILITY}"
+
+# Remove components that are not desired.
+# We do not care whether a component is present in the `require` or
+# `require-dev` section; we will attempt to remove each request from
+# both. This may produce warning messages.
+[[ -z "${REMOVALS}" ]] || composer -n --working-dir=$dir remove --no-update ${REMOVALS}
+[[ -z "${REMOVALS}" ]] || composer -n --working-dir=$dir remove --no-update --dev ${REMOVALS} >/dev/null 2>&1
+
+# Add a constraint
+[[ -z "${REQUIREMENTS}" ]] || composer -n --working-dir=$dir require --dev --no-update ${REQUIREMENTS}
+
+# Never commit a cached 'vendor' directory in the scenario folder
+echo 'vendor' > $dir/.gitignore
+
+# Create a lockfile via `composer update`, if requested
+if $CREATE_LOCKFILE ; then
+
+ # Temporarily set our vendor directory to 'vendor'
+ composer -n --working-dir=$dir config vendor-dir vendor
+
+ # Create the composer.lock file. Ignore the vendor directory created.
+ composer -n --working-dir=$dir update --no-scripts
+
+else
+
+ # If we are not storing a composer.lock, mark it as ignored if
+ # transiently generated in the future
+ echo 'composer.lock' >> $dir/.gitignore
+
+fi
+
+# Set the vendor directory to its final desired location.
+composer -n --working-dir=$dir config vendor-dir '../../vendor'
+
+# The 'autoload' section specifies directory paths that are relative
+# to the composer.json file. We will drop in some symlinks so that
+# these paths will resolve as if the composer.json were in the root.
+for target in ${AUTOLOAD_DIRECTORIES} ; do
+ [[ ! -d "$target" ]] || ln -s -f ../../$target $dir
+done
+
+# Copy our install-scenario script in so that it may be committed with our composer.lock files
+cp -f ${SELF_DIRNAME}/install-scenario $dir/../install
+chmod +x $dir/../install