123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- #!/usr/bin/env bash
-
- TRACK=java
- TRACK_REPO="$TRACK"
- TRACK_SRC_EXT="java"
- CPU_CORES=`getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1`
- EXERCISES_TO_SOLVE=$@
-
- on_exit() {
- echo ">>> on_exit()"
- if [[ "$xapi_pid" != "" ]] ; then
- kill $xapi_pid
- echo "stopped x-api (pid=${xapi_pid})"
- fi
- cd $EXECPATH
- echo "<<< on_exit()"
- }
-
- assert_installed() {
- local binary=$1
- echo ">>> assert_installed(binary=\"${binary}\")"
-
- if [[ "`which $binary`" == "" ]]; then
- echo "${binary} not found; it is required to perform this test."
- echo -e "Have you completed the setup instructions at https://github.com/exercism/${TRACK_REPO} ?\n"
- echo "PATH=${PATH}"
- echo "aborting."
- exit 1
- fi
- echo "<<< assert_installed()"
- }
-
- assert_ruby_installed() {
- local ruby_app_home="$1"
- echo ">>> assert_ruby_installed(ruby_app_home=\"${ruby_app_home}\")"
-
- pushd "${ruby_app_home}"
- local current_ruby_ver=`ruby --version | egrep --only-matching "[0-9]+\.[0-9]+\.[0-9]+"`
- local expected_ruby_ver=`cat Gemfile | awk -F\' '/ruby /{print $2}'`
- popd
- if [[ "${expected_ruby_ver}" != "" && "${current_ruby_ver}" != "${expected_ruby_ver}" ]]; then
- echo "${ruby_app_home} requires Ruby ${expected_ruby_ver}; current Ruby version is ${current_ruby_ver}."
- echo -e "Ruby used: `which ruby`.\n"
- echo -e "Have you completed the setup instructions at https://github.com/exercism/${TRACK_REPO} ?\n"
- echo "PATH=${PATH}"
- echo "aborting."
- exit 1
- fi
- echo "<<< assert_ruby_installed()"
- }
-
- clean() {
- local build_dir="$1"
- echo ">>> clean(build_dir=\"${build_dir}\")"
-
- # empty, absolute path, or parent reference are considered dangerous to rm -rf against.
- if [[ "${build_dir}" == "" || ${build_dir} =~ ^/ || ${build_dir} =~ \.\. ]] ; then
- echo "Value for build_dir looks dangerous. Aborting."
- exit 1
- fi
-
- local build_path=$( pwd )/${build_dir}
- if [[ -d "${build_path}" ]] ; then
- echo "Cleaning journey script build output directory (${build_path})."
- rm -rf "${build_path}"
- fi
- cd exercises
- "$EXECPATH"/gradlew clean
- cd ..
- echo "<<< clean()"
- }
-
- get_operating_system() {
- case $(uname) in
- (Darwin*)
- echo "mac";;
- (Linux*)
- echo "linux";;
- (Windows*)
- echo "windows";;
- (MINGW*)
- echo "windows";;
- (*)
- echo "linux";;
- esac
- }
-
- get_cpu_architecture() {
- case $(uname -m) in
- (*64*)
- echo 64bit;;
- (*686*)
- echo 32bit;;
- (*386*)
- echo 32bit;;
- (*)
- echo 64bit;;
- esac
- }
-
- get_optimal_amount_of_jobs() {
- if [ "$CPU_CORES" -gt "1" ]; then
- echo $((CPU_CORES-1))
- else
- echo 1
- fi
- }
-
- download_exercism_cli() {
- local os="$1"
- local arch="$2"
- local exercism_home="$3"
- echo ">>> download_exercism_cli(os=\"${os}\", arch=\"${arch}\", exercism_home=\"${exercism_home}\")"
-
- local CLI_RELEASES=https://github.com/exercism/cli/releases
-
- local latest=${CLI_RELEASES}/latest
- # "curl..." :: HTTP 302 headers, including "Location" -- URL to redirect to.
- # "awk..." :: pluck last path segment from "Location" (i.e. the version number)
- local version="$(curl --head --silent ${latest} | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
-
- local download_url_suffix
- local unzip_command
- local unzip_from_file_option
- if [[ ${os} == "windows" ]] ; then
- download_url_suffix="zip"
- unzip_command="unzip -d"
- unzip_from_file_option=""
- else
- download_url_suffix="tgz"
- unzip_command="tar xz -C"
- unzip_from_file_option="-f"
- fi
- local download_url=${CLI_RELEASES}/download/${version}/exercism-${os}-${arch}.${download_url_suffix}
-
- mkdir -p ${exercism_home}
- local temp=`mktemp`
- curl -s --location ${download_url} > ${temp}
- ${unzip_command} ${exercism_home} ${unzip_from_file_option} ${temp}
- echo "<<< download_exercism_cli()"
- }
-
- git_clone() {
- local repo_name="$1"
- local dest_path="$2"
- echo ">>> git_clone(repo_name=\"${repo_name}\", dest_path=\"${dest_path}\")"
-
- git clone https://github.com/exercism/${repo_name} ${dest_path}
-
- echo "<<< git_clone()"
- }
-
- make_local_trackler() {
- local trackler="$1"
- local xapi_home="$2"
- echo ">>> make_local_trackler(trackler=\"${trackler}\", xapi_home=\"${xapi_home}\")"
-
- local track_root=$( pwd )
- pushd ${trackler}
-
- # Get the version of Trackler x-api is currently using
- local version=$( grep -m 1 'trackler' ${xapi_home}/Gemfile.lock | sed 's/.*(//' | sed 's/)//' )
-
- git checkout v${version}
- git submodule init -- problem-specifications
- git submodule update
-
- # Bake in local copy of this track; this is what we are testing.
- rmdir tracks/${TRACK}
- mkdir -p tracks/${TRACK}/exercises
- cp ${track_root}/config.json tracks/${TRACK}
- cp -r ${track_root}/exercises tracks/${TRACK}
-
- gem install bundler
- bundle install --jobs $(get_optimal_amount_of_jobs)
- gem build trackler.gemspec
-
- # Make *this* the gem that x-api uses when we build x-api.
- gem install --local trackler-*.gem
-
- popd > /dev/null
- echo "<<< make_local_trackler()"
- }
-
- start_x_api() {
- local xapi_home="$1"
- echo ">>> start_x_api(xapi_home=\"${xapi_home}\")"
-
- pushd $xapi_home
-
- gem install bundler
- bundle install --jobs $(get_optimal_amount_of_jobs)
- RACK_ENV=development rackup &
- xapi_pid=$!
- sleep 5
-
- echo "x-api is running (pid=${xapi_pid})."
-
- popd > /dev/null
- echo "<<< start_x_api()"
- }
-
- configure_exercism_cli() {
- local exercism_home="$1"
- local exercism_configfile="$2"
- local xapi_port=$3
- echo ">>> configure_exercism_cli(exercism_home=\"${exercism_home}\", exercism_configfile=\"${exercism_configfile}\", xapi_port=${xapi_port})"
- local exercism="./exercism --config ${exercism_configfile}"
-
- mkdir -p "${exercism_home}"
- pushd "${exercism_home}"
- $exercism configure --dir="${exercism_home}"
- $exercism configure --api http://localhost:${xapi_port}
- $exercism debug
- popd
-
- echo "<<< configure_exercism_cli()"
- }
-
- solve_all_exercises() {
- local exercism_exercises_dir="$1"
- local exercism_configfile="$2"
- echo ">>> solve_all_exercises(exercism_exercises_dir=\"${exercism_exercises_dir}\", exercism_configfile=\"${exercism_configfile}\")"
-
- local track_root=$( pwd )
- local exercism_cli="./exercism --config ${exercism_configfile}"
- local exercises=`cat config.json | jq '.exercises[].slug + " "' --join-output`
- local total_exercises=`cat config.json | jq '.exercises | length'`
- local current_exercise_number=1
- local tempfile="${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt"
-
- pushd ${exercism_exercises_dir}
- for exercise in $exercises; do
- echo -e "\n\n"
- echo "=================================================="
- echo "${current_exercise_number} of ${total_exercises} -- ${exercise}"
- echo "=================================================="
-
- ${exercism_cli} fetch ${TRACK} $exercise
- cp -R -H ${track_root}/exercises/${exercise}/.meta/src/reference/${TRACK}/* ${exercism_exercises_dir}/${TRACK}/${exercise}/src/main/${TRACK}/
-
- pushd ${exercism_exercises_dir}/${TRACK}/${exercise}
- # Check that tests compile before we strip @Ignore annotations
- "$EXECPATH"/gradlew compileTestJava
- # Ensure we run all the tests (as delivered, all but the first is @Ignore'd)
- for testfile in `find . -name "*Test.${TRACK_SRC_EXT}"`; do
- # Strip @Ignore annotations to ensure we run the tests (as delivered, all but the first is @Ignore'd).
- # Note that unit-test.sh also strips @Ignore annotations via the Gradle task copyTestsFilteringIgnores.
- # The stripping implementations here and in copyTestsFilteringIgnores should be kept consistent.
- sed 's/@Ignore\(\(.*\)\)\{0,1\}//' ${testfile} > "${tempfile}" && mv "${tempfile}" "${testfile}"
- done
- "$EXECPATH"/gradlew test
- popd
-
- current_exercise_number=$((current_exercise_number + 1))
- done
- popd
- }
-
- solve_single_exercise() {
- local exercism_exercises_dir="$1"
- local exercism_configfile="$2"
- local exercise_to_solve="$3"
- echo ">>> solve_all_exercises(exercism_exercises_dir=\"${exercism_exercises_dir}\", exercism_configfile=\"${exercism_configfile}\", exercise_to_solve=\"$exercise_to_solve\")"
-
- local track_root=$( pwd )
- local exercism_cli="./exercism --config ${exercism_configfile}"
- local tempfile="${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt"
-
- pushd ${exercism_exercises_dir}
-
- echo -e "\n\n"
- echo "=================================================="
- echo "Solving ${exercise_to_solve}"
- echo "=================================================="
-
- ${exercism_cli} fetch ${TRACK} $exercise_to_solve
- cp -R -H ${track_root}/exercises/${exercise_to_solve}/.meta/src/reference/${TRACK}/* ${exercism_exercises_dir}/${TRACK}/${exercise_to_solve}/src/main/${TRACK}/
-
- pushd ${exercism_exercises_dir}/${TRACK}/${exercise_to_solve}
- # Check that tests compile before we strip @Ignore annotations
- "$EXECPATH"/gradlew compileTestJava
- # Ensure we run all the tests (as delivered, all but the first is @Ignore'd)
- for testfile in `find . -name "*Test.${TRACK_SRC_EXT}"`; do
- # Strip @Ignore annotations to ensure we run the tests (as delivered, all but the first is @Ignore'd).
- # Note that unit-test.sh also strips @Ignore annotations via the Gradle task copyTestsFilteringIgnores.
- # The stripping implementations here and in copyTestsFilteringIgnores should be kept consistent.
- sed 's/@Ignore\(\(.*\)\)\{0,1\}//' ${testfile} > "${tempfile}" && mv "${tempfile}" "${testfile}"
- done
- "$EXECPATH"/gradlew test
- popd
-
- popd
- }
-
- main() {
- # all functions assume current working directory is repository root.
- cd "${SCRIPTPATH}/.."
-
- local track_root=$( pwd )
- local build_dir="build"
- local build_path="${track_root}/${build_dir}"
-
- local xapi_home="${build_path}/x-api"
- local trackler_home="${build_path}/trackler"
- local exercism_home="${build_path}/exercism"
-
- local exercism_configfile=".journey-test.exercism.json"
- local xapi_port=9292
-
- # fail fast if required binaries are not installed.
- assert_installed "jq"
-
- clean "${build_dir}"
-
- # Download everything we need in parallel
- git_clone "x-api" "${xapi_home}" &
- git_clone "trackler" "${trackler_home}" &
- download_exercism_cli $(get_operating_system) $(get_cpu_architecture) "${exercism_home}" &
- wait
-
- # Check and install the ruby stuff we need in parallel
- assert_ruby_installed "${trackler_home}" &
- assert_ruby_installed "${xapi_home}" &
- wait
-
- # Make a local version of trackler
- make_local_trackler "${trackler_home}" "${xapi_home}"
-
- # Start-up a local instance of x-api so we can fetch the exercises through it.
- start_x_api "${xapi_home}"
-
- # Create a CLI install and config just for this build; this script does not use your CLI install.
- configure_exercism_cli "${exercism_home}" "${exercism_configfile}" "${xapi_port}"
-
- if [[ $EXERCISES_TO_SOLVE == "" ]]; then
- solve_all_exercises "${exercism_home}" "${exercism_configfile}"
- else
- for exercise in $EXERCISES_TO_SOLVE
- do solve_single_exercise "${exercism_home}" "${exercism_configfile}" "${exercise}"
- done
- fi
- }
-
- ##########################################################################
- # Execution begins here...
-
- # If any command fails, fail the script.
- set -ex
- SCRIPTPATH=$( pushd `dirname $0` > /dev/null && pwd && popd > /dev/null )
- EXECPATH=$( pwd )
- # Make output easier to read in CI
- TERM=dumb
-
- xapi_pid=""
- trap on_exit EXIT
- main
-
|