From a219dbf8f80c345eb58d512cfe78b6cc14e48725 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 20 Jan 2014 11:43:27 +0900 Subject: [PATCH 1/3] Add install script --- install.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 install.sh diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..7ea0326 --- /dev/null +++ b/install.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Usage: PREFIX=/usr/local ./install.sh +# +# Installs pyenv-virtualenv under $PREFIX. + +set -e + +cd "$(dirname "$0")" + +if [ -z "${PREFIX}" ]; then + PREFIX="/usr/local" +fi + +LIBEXEC_PATH="${PREFIX}/libexec" + +mkdir -p "$LIBEXEC_PATH" + +install -p libexec/* "$LIBEXEC_PATH" From ee4d2632da27ae738dfa08497894c75c75302e9b Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 20 Jan 2014 11:47:34 +0900 Subject: [PATCH 2/3] Add tests --- etc/pyenv.d/exec/pip.bash | 2 +- install.sh | 3 + test/installer.bats | 42 ++++++++++++ test/libexec/pyenv-exec | 17 +++++ test/pip.bats | 133 ++++++++++++++++++++++++++++++++++++++ test/stubs/stub | 109 +++++++++++++++++++++++++++++++ test/test_helper.bash | 99 ++++++++++++++++++++++++++++ 7 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 test/installer.bats create mode 100755 test/libexec/pyenv-exec create mode 100644 test/pip.bats create mode 100755 test/stubs/stub create mode 100644 test/test_helper.bash diff --git a/etc/pyenv.d/exec/pip.bash b/etc/pyenv.d/exec/pip.bash index 303f596..dc9fc49 100644 --- a/etc/pyenv.d/exec/pip.bash +++ b/etc/pyenv.d/exec/pip.bash @@ -18,7 +18,7 @@ abs_dirname() { cd "$cwd" } -PYENV_PIP_REHASH_ROOT="$(abs_dirname "${BASH_SOURCE[0]}")/../../.." +PYENV_PIP_REHASH_ROOT="$(abs_dirname "$(abs_dirname "${BASH_SOURCE[0]}")/../../../..")" if [ -x "${PYENV_PIP_REHASH_ROOT}/libexec/${PYENV_COMMAND##*/}" ]; then PYENV_COMMAND_PATH="${PYENV_PIP_REHASH_ROOT}/libexec/${PYENV_COMMAND##*/}" diff --git a/install.sh b/install.sh index 7ea0326..4107cb0 100755 --- a/install.sh +++ b/install.sh @@ -11,8 +11,11 @@ if [ -z "${PREFIX}" ]; then PREFIX="/usr/local" fi +ETC_PATH="${PREFIX}/etc/pyenv.d" LIBEXEC_PATH="${PREFIX}/libexec" +mkdir -p "$ETC_PATH" mkdir -p "$LIBEXEC_PATH" +cp -RPp etc/pyenv.d/* "$ETC_PATH" install -p libexec/* "$LIBEXEC_PATH" diff --git a/test/installer.bats b/test/installer.bats new file mode 100644 index 0000000..5cd0318 --- /dev/null +++ b/test/installer.bats @@ -0,0 +1,42 @@ +#!/usr/bin/env bats + +load test_helper + +@test "installs pyenv-pip-rehash into PREFIX" { + cd "$TMP" + PREFIX="${PWD}/usr" run "${BATS_TEST_DIRNAME}/../install.sh" + assert_success "" + + cd usr + + assert [ -x libexec/pip ] + assert [ -f etc/pyenv.d/exec/pip.bash ] +} + +@test "overwrites old installation" { + cd "$TMP" + mkdir -p libexec + touch libexec/pip + + PREFIX="$PWD" run "${BATS_TEST_DIRNAME}/../install.sh" + assert_success "" + + assert [ -x libexec/pip ] + run grep "pyenv-rehash" libexec/pip + assert_success +} + +@test "unrelated files are untouched" { + cd "$TMP" + mkdir -p libexec share/bananas + chmod g-w libexec + touch libexec/bananas + + PREFIX="$PWD" run "${BATS_TEST_DIRNAME}/../install.sh" + assert_success "" + + assert [ -e libexec/bananas ] + + run ls -ld libexec + assert_equal "r-x" "${output:4:3}" +} diff --git a/test/libexec/pyenv-exec b/test/libexec/pyenv-exec new file mode 100755 index 0000000..29c1ecd --- /dev/null +++ b/test/libexec/pyenv-exec @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +PYENV_COMMAND="$1" +PYENV_COMMAND_PATH="$(pyenv-which "$PYENV_COMMAND")" +PYENV_BIN_PATH="${PYENV_COMMAND_PATH%/*}" + +shopt -s nullglob +for script in "$(dirname "${BASH_SOURCE[0]}")/../../etc/pyenv.d/exec/"*.bash; do + source "${script}" +done +shopt -u nullglob + +shift 1 +echo PYENV_BIN_PATH="${PYENV_BIN_PATH}" exec -a "${PYENV_COMMAND}" "$PYENV_COMMAND_PATH" "$@" +exec -a "${PYENV_COMMAND}" "$PYENV_COMMAND_PATH" "$@" diff --git a/test/pip.bats b/test/pip.bats new file mode 100644 index 0000000..8a21f69 --- /dev/null +++ b/test/pip.bats @@ -0,0 +1,133 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + export PYENV_PIP_REHASH_ROOT="$(abs_dirname "${BATS_TEST_DIRNAME}/../..")" +} + +resolve_link() { + $(type -p greadlink readlink | head -1) "$1" +} + +abs_dirname() { + local cwd="$(pwd)" + local path="$1" + + while [ -n "$path" ]; do + cd "${path%/*}" + local name="${path##*/}" + path="$(resolve_link "$name" || true)" + done + + pwd + cd "$cwd" +} + +@test "should not invoke rehash after pip freeze" { + stub pyenv-which "pip : echo \"${TMP}/bin/pip\"" \ + "pip : echo \"${TMP}/bin/pip\"" + stub pyenv-rehash "echo rehashed" + stub pip "echo \"pip \$@\"" + + run pyenv-exec pip freeze + + assert_success + assert_output <&${!_STUB_DEBUG} +fi + +[ -e "${!_STUB_PLAN}" ] || exit 1 +[ -n "${!_STUB_RUN}" ] || eval "${_STUB_RUN}"="${TMPDIR}/${program}-stub-run" + + +# Initialize or load the stub run information. +eval "${_STUB_INDEX}"=1 +eval "${_STUB_RESULT}"=0 +[ ! -e "${!_STUB_RUN}" ] || source "${!_STUB_RUN}" + + +# Loop over each line in the plan. +index=0 +while IFS= read -r line; do + index=$(($index + 1)) + + if [ -z "${!_STUB_END}" ] && [ $index -eq "${!_STUB_INDEX}" ]; then + # We found the plan line we're interested in. + # Start off by assuming success. + result=0 + + # Split the line into an array of arguments to + # match and a command to run to produce output. + command=" $line" + if [ "$command" != "${command/ : }" ]; then + patterns="${command%% : *}" + command="${command#* : }" + fi + + # Naively split patterns by whitespace for now. + # In the future, use a sed script to split while + # respecting quoting. + set -f + patterns=($patterns) + set +f + arguments=("$@") + + # Match the expected argument patterns to actual + # arguments. + for (( i=0; i<${#patterns[@]}; i++ )); do + pattern="${patterns[$i]}" + argument="${arguments[$i]}" + + case "$argument" in + $pattern ) ;; + * ) result=1 ;; + esac + done + + # If the arguments matched, evaluate the command + # in a subshell. Otherwise, log the failure. + if [ $result -eq 0 ] ; then + set +e + ( eval "$command" ) + status="$?" + set -e + else + eval "${_STUB_RESULT}"=1 + fi + fi +done < "${!_STUB_PLAN}" + + +if [ -n "${!_STUB_END}" ]; then + # Clean up the run file. + rm -f "${!_STUB_RUN}" + + # If the number of lines in the plan is larger than + # the requested index, we failed. + if [ $index -ge "${!_STUB_INDEX}" ]; then + eval "${_STUB_RESULT}"=1 + fi + + # Return the result. + exit "${!_STUB_RESULT}" + +else + # If the requested index is larger than the number + # of lines in the plan file, we failed. + if [ "${!_STUB_INDEX}" -gt $index ]; then + eval "${_STUB_RESULT}"=1 + fi + + # Write out the run information. + { echo "${_STUB_INDEX}=$((${!_STUB_INDEX} + 1))" + echo "${_STUB_RESULT}=${!_STUB_RESULT}" + } > "${!_STUB_RUN}" + + exit "$status" + +fi diff --git a/test/test_helper.bash b/test/test_helper.bash new file mode 100644 index 0000000..5d8cdf4 --- /dev/null +++ b/test/test_helper.bash @@ -0,0 +1,99 @@ +export TMP="$BATS_TEST_DIRNAME/tmp" + +PATH=/usr/bin:/usr/sbin:/bin/:/sbin +PATH="$BATS_TEST_DIRNAME/../bin:$PATH" +PATH="$BATS_TEST_DIRNAME/libexec:$PATH" +PATH="$TMP/bin:$PATH" +export PATH + +teardown() { + rm -fr "$TMP"/* +} + +stub() { + local program="$1" + local prefix="$(echo "$program" | tr a-z- A-Z_)" + shift + + export "${prefix}_STUB_PLAN"="${TMP}/${program}-stub-plan" + export "${prefix}_STUB_RUN"="${TMP}/${program}-stub-run" + export "${prefix}_STUB_END"= + + mkdir -p "${TMP}/bin" + ln -sf "${BATS_TEST_DIRNAME}/stubs/stub" "${TMP}/bin/${program}" + + touch "${TMP}/${program}-stub-plan" + for arg in "$@"; do printf "%s\n" "$arg" >> "${TMP}/${program}-stub-plan"; done +} + +unstub() { + local program="$1" + local prefix="$(echo "$program" | tr a-z- A-Z_)" + local path="${TMP}/bin/${program}" + + export "${prefix}_STUB_END"=1 + + local STATUS=0 + "$path" || STATUS="$?" + + rm -f "$path" + rm -f "${TMP}/${program}-stub-plan" "${TMP}/${program}-stub-run" + return "$STATUS" +} + +assert() { + if ! "$@"; then + flunk "failed: $@" + fi +} + +flunk() { + { if [ "$#" -eq 0 ]; then cat - + else echo "$@" + fi + } | sed "s:${TMP}:\${TMP}:g" >&2 + return 1 +} + +assert_success() { + if [ "$status" -ne 0 ]; then + { echo "command failed with exit status $status" + echo "output: $output" + } | flunk + elif [ "$#" -gt 0 ]; then + assert_output "$1" + fi +} + +assert_failure() { + if [ "$status" -eq 0 ]; then + flunk "expected failed exit status" + elif [ "$#" -gt 0 ]; then + assert_output "$1" + fi +} + +assert_equal() { + if [ "$1" != "$2" ]; then + { echo "expected: $1" + echo "actual: $2" + } | flunk + fi +} + +assert_output() { + local expected + if [ $# -eq 0 ]; then expected="$(cat -)" + else expected="$1" + fi + assert_equal "$expected" "$output" +} + +assert_output_contains() { + local expected="$1" + echo "$output" | grep -F "$expected" >/dev/null || { + { echo "expected output to contain $expected" + echo "actual: $output" + } | flunk + } +} From 120d62d6e52bb501c85474d6dcc0237556cd67b0 Mon Sep 17 00:00:00 2001 From: Yamashita Yuu Date: Mon, 20 Jan 2014 23:37:54 +0900 Subject: [PATCH 3/3] Add .travis.yml --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1eaa4a9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +install: git clone https://github.com/sstephenson/bats.git +script: bats/bin/bats --tap test +language: c +notifications: + email: + on_success: never